题意:给出一个数t和还有n个数,求出从n个数中任意取出若干个,使得这若干个数之和等于t的所有方案,要求每个方案中的数由大到小,并且所有方案的输出顺序也是从大到小。n个数已经按照降序排好。
思路:深搜,注意不能搜重了,每次搜时,只能和比当前数小的数进行组合,搜完当前数后还要跳过后面与当前数相等的所有数(否则都会重复),另外只要搜索方案正确,顺序这东西可以不用考虑,另外手残打错了一个字母,TLE了半天。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<strstream>
#define MAXN 110
using namespace std;
int t, n;
int num[MAXN];
bool vis[MAXN];
int cnt;
int ans[MAXN];
int ca;
bool ok;
void display()
{
for(int i = 0; i < ca; i++)
{
if(i) printf("+%d", ans[i]);
else printf("%d", ans[i]);
}
printf("\n");
}
void dfs(int p, int sum)
{
if(sum == 0)
{
display();
ok = 1;
}
for(int i = p; i < n; i++)
{
if(!vis[i] && sum - num[i] >= 0)
{
vis[i] = 1;
ans[ca++] = num[i];
dfs(i+1, sum-num[i]);
ca--;
vis[i] = 0;
while(i+1 < n && num[i+1] == num[i]) i++;
}
}
}
int main()
{
//freopen("C:/Users/Admin/Desktop/in.txt", "r", stdin);
while(scanf("%d%d", &t, &n) != -1)
{
ok = 0;
if(t == 0 || n == 0) return 0;
cnt = 0;
ca = 0;
memset(vis, 0, sizeof(vis));
for(int i = 0; i < n; i++) scanf("%d", &num[i]);
printf("Sums of %d:\n", t);
dfs(0, t);
if(!ok) printf("NONE\n");
//sort(ans, ans+ca);
}
return 0;
}