https://vjudge.net/contest/425321#problem/B
题意概括
给一串单调不增的数字,用这些数字凑出一个整数。经典的凑数字问题。但是比较麻烦的是输出,需要输出所有的可能情况,并且不能有重复。
思路
如何做到不重复呢?
方法是,在dfs的时候,记录下已经选到的数字的下标。我们首先要保证选到的数字的下标是单调递增的。
其次,因为一串数字可能会有重复的,所以当我们一次dfs搜完后,我们要剔除重复的数字。具体方法见下。
代码
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
int t,n,flag=0;
int a[15],res[15],vis[15];
int cmp(int a,int b)
{
return a>b;
}
void dfs(int pos,int sum,int step)
{
int i;
if(sum==t)
{
flag=1;
printf("%d",res[1]);
for(i=2;i<step;i++)
{
printf("+%d",res[i]);
}
printf("\n");
}
else
{
for(i=pos;i<=n;i++)///下标从pos开始枚举
{
if(!vis[i]&&sum+a[i]<=t)
{
vis[i]=1;
res[step]=a[i];
dfs(i,sum+a[i],step+1);
vis[i]=0;
while(a[i]==a[i+1]) i++;
///去重
}
}
}
}
int main()
{
while(~scanf("%d%d",&t,&n)&&n)
{
memset(vis,0,sizeof(vis));
int i;
flag=0;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
sort(a+1,a+1+n,cmp);///倒过来排一下,便于输出
printf("Sums of %d:\n",t);
dfs(1,0,1);
if(!flag) printf("NONE\n");
}
return 0;
}