#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int cmp(const void *a, const void *b)
{
return *(int *)b - *(int *)a;
}
int n,k;
int map[110];
int l[110];
int suss;//用来标记是否成功
void dfs( int b, int c, int d)//pos代表第几个数为位置
{
int i;
if(c > k)
{
return ;
}
if(c == k)//如果找到答案输出
{
suss ++;
for(i = 0; i < d; ++i)
{
if(i == 0)
printf("%d", l[i]);
else
printf("+%d", l[i]);
}
printf("\n");
}
for(i = b;i <= n; i++)//对当前位进行遍历
{
l[d] = map[i];//保存路径
dfs( i+1, c + map[i], d+1);//对下一个数进行遍历
while(i+1 <= n && map[i] == map[i+1])//去重
i++;
}
}
int main()
{
int i;
while(scanf("%d%d",&k,&n)&& (n || k))
{
suss=0;
for(i=1;i<=n;i++)
scanf("%d",&map[i]);
qsort(map + 1, n, sizeof(map[0]), cmp);
printf("Sums of %d:\n",k);
dfs(1, 0, 0);
if(suss==0)
printf("NONE\n");
}
return 0;
}
题意:给出n个数和一个整数,并且这n个数是以非递增的顺序给出的,求这n个数中任意个数字的和等于给出的整数的组合有多少种,并且以非递增的顺序输出序列。
思路:深搜题,唯一值得注意的就是去重,对于n个重复的数字,我们对每一位进行遍历,先遍历后回溯,倘若找到答案直接输出序列,回溯的时候对当前位进行去重,即对当前位进行下一次遍历的时候如果数字和上一次的一样则跳过该位。