错误代码,过不了的数据14:15 10 17 16 12 1 10 20 17 19 4 5 9 5 可能解:(20 15 5 ),(19 17 4 ),( 17 12 10 1 ), ( 16 10 9 5 )
下面的代码“no”,因为(20 19 1),(17接下来凑不出来 )
#include<iostream>
#include<cstdlib>
#include<algorithm>
using namespace std;
int length[21];
int mark[21];
bool cmp(int x,int y)
{
return x>y;
}
int dfs(int sum,int flag,int n,int time)//´Ótime¿ªÊ¼ËÑË÷
{
if(sum==0)return 1;
if(time<n)
{
for(int k=time;k<n;k++)
{
if(mark[k]<0&&sum-length[k]>=0)
{
mark[k]=flag;
if(dfs(sum-length[k],flag,n,k+1))
return 1;
else
mark[k]=-1;
}
}
}
return 0;
}
int main()
{
freopen("s.txt","r",stdin);
freopen("key.txt","w",stdout);
int num,n;
cin>>num;
while(num--)
{
int sum=0;
cin>>n;
for(int k=0;k<n;k++)
{
cin>>length[k];
mark[k]=-1;
sum+=length[k];
}
sort(length,length+n,cmp);
if(sum%4!=0||length[0]>sum/4)
cout<<"no"<<endl;
else
{
sum/=4;
if(dfs(sum,1,n,0))
{
if(dfs(sum,2,n,0))
{
if(dfs(sum,3,n,0))
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
}
else
cout<<"no"<<endl;
}
else
cout<<"no"<<endl;
}
}
//system("PAUSE");
return 0;
}
正确的解法应当是,在一起搜索。
下面是一段超时的代码
#include<iostream>
#include<cstdlib>
#include<algorithm>
using namespace std;
int length[21];
int mark[21];
int flag=0;
int target;
bool cmp(int x,int y)
{
return x>y;
}
int func(int i)
{
while(mark[i]>0)
i++;
return i;
}
void dfs(int sum,int n,int time,int level)//从序号为time的开始搜索
{
if(flag)return ;
if(sum==0&&level==3)
{
flag=1;
return;
}
if(sum==0)
{
level++;
dfs(target,n,func(0),level);
}
else if(time<n)
{
for(int k=time;k<n;k++)
{
if(k>1)
{
if(length[k]==length[k-1]&&!mark[k-1])
continue;//显然
}
if(sum<length[n-1]) continue;//显然
if(mark[k]<0&&sum-length[k]>=0)
{
mark[k]=1;
dfs(sum-length[k],n,func(k+1),level);
mark[k]=-1;
}
}
}
}
int main()
{
freopen("s.txt","r",stdin);
freopen("key.txt","w",stdout);
int num,n;
cin>>num;
while(num--)
{
int sum=0;
cin>>n;
for(int k=0;k<n;k++)
{
cin>>length[k];
mark[k]=-1;
sum+=length[k];
}
sort(length,length+n,cmp);
if(sum%4!=0||length[0]>sum/4)
cout<<"no"<<endl;
else
{
sum/=4;
target=sum;
dfs(sum,n,0,0);
if(flag==0)
cout<<"no"<<endl;
else
cout<<"yes"<<endl;
}
}
//system("PAUSE");
return 0;
}
上面超时就超时原因是减枝不彻底。level标记也不太好
决定另外炉灶,先看看别人的代码
#include<iostream>
#include<algorithm>
using namespace std;
int s[21];
int v[21];
int len;
int m;
int dfs(int cur,int num,int beg,int fin)
{
int solve(int );
if(num==1)
return 1;
if(cur==len)
{
return solve(num-1);
}
for(int i=beg;i>=fin;i--)
{
if(!v[i]&&cur+s[i]<=len)
{
v[i]=1;
if(dfs(cur+s[i],num,i-1,fin))
return 1;
v[i]=0;
}
}
return 0;
}
int solve(int edge_num)
{
int i;
for(i=m;i>=1;i--)
if(!v[i])
{
v[i]=1;
if(dfs( s[i],edge_num,i-1,1))
return 1;
v[i]=0;
}
return 0;
}
int main()
{
int n;
cin>>n;
while(n--)
{
cin>>m;
int i;
int sum=0;
for(i=1;i<=m;i++)
{
cin>>s[i];
sum+=s[i];
v[i]=0;
}
len=sum/4;
if(4*len!=sum)
{
cout<<"no"<<endl;
continue;
}
sort(s+1,s+m+1);
if(s[m]>len)
{
cout<<"no"<<endl;
continue;
}
if(solve(4))
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
}
return 0;
}//剪枝还可以做得更好!!!
人家的solve写得好!!,结合dfs.