题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1711
思路;dfs搜索,把所有可能的情况存下来,重复的标记掉,输出结果
#include<cstdio>
#include<cstring>
using namespace std;
const int N=5000;
int t,cnt,p,flag,sum,n,ans[N][13],isok[N],len[N],map[13],tmp[13];
void dfs(int d)
{
int i;
if(sum==t)
{
flag=1;
for(i=0;i<p;i++)
ans[cnt][i]=tmp[i];
len[cnt]=p;
cnt++;
return ;
}
for(i=d;i<n;i++)
{
if(sum+map[i]<=t)
{
tmp[p++]=map[i];
sum+=map[i];
dfs(i+1);
sum-=map[i];
p--;
}
}
}
int cmp(int a,int b)
{
int i;
if(len[a]!=len[b])
return 1;
else
{
for(i=0;i<len[a];i++)
if(ans[a][i]!=ans[b][i])
return 1;
}
return 0;
}
void outp()
{
int i,j;
memset(isok,0,sizeof(isok));
for(i=0;i<cnt;i++)
{
if(isok[i]==1)
continue;
for(j=i+1;j<cnt;j++)
{
if(cmp(i,j)==0)
isok[j]=1;
}
}
for(i=0;i<cnt;i++)
{
if(isok[i])
continue;
for(j=0;j<len[i];j++)
{
if(j==0)
printf("%d",ans[i][j]);
else
printf("+%d",ans[i][j]);
}
printf("\n");
}
}
int main()
{
int i;
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(scanf("%d%d",&t,&n)!=EOF)
{
cnt=0;
if(n==0)
break;
for(i=0;i<n;i++)
scanf("%d",&map[i]);
flag=0;sum=0;cnt=0;p=0;
dfs(0);
printf("Sums of %d:\n",t);
outp();
if(!flag)
printf("NONE\n");
}
return 0;
}