链接:
http://poj.org/problem?id=1564
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=88230#problem/F
给了一个数 m,给一个由 n 个数组成的数组 a[] , 求和为 m 的 a[] 的子集
pos 代表的是搜到第 pos 个元素,ans 代表的是 b[] 数组中存的第 ans 个数
我一定要学会深搜!!!
代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int n, m, flag; int a[11000], b[11000]; int cmp(int a, int b) { return a > b; }
///pos 代表的是搜到第 pos 个元素,
///ans 代表的是 b[] 数组中存的第 ans 个数, b[] 数组里存的是和为 sum 的
void dfs(int pos , int ans, int sum)
{ if(sum == n) { flag = 1; sort(b, b + ans, cmp); for(int i = 0; i < ans; ++i) { if(!i) printf("%d",b[i]); else if(i) printf("+%d",b[i]); } printf("\n"); return; } for(int i = pos; i < m; ++i) { if(sum + a[i] <= n) { b[ans] = a[i]; dfs(i + 1, ans + 1, sum + a[i]); while(i + 1 < m && a[i] == a[i + 1])//去重 ++i; } } }
/*去重:
例如:3 3 2 1 1
为了防止出现 2+1
2+1
这样的重复数据
刚看时我连去重的意思都弄错了,不知道是什么意思,还好调试了一遍知道了 */ int main () { while(scanf("%d%d", &n, &m), n || m) { for(int i = 0; i < m; ++i) scanf("%d", &a[i]); flag = 0; sort(a, a + m, cmp); printf("Sums of %d:\n", n); dfs(0, 0, 0); if(!flag) printf("NONE\n"); } return 0; }
勿忘初心