小记:起初以为是一道非常水的dfs暴搜题,然后写完测试一看,蒙了。 相同的答案太多,也就是说,我将相同的数字都看出是不一样的了,实际上都是相同的,
也就是说我没判重。于是就必须加个判重,但是这样又不好做了,标记判重不可能。
思路:对每个数值记录出现了多少次,然后对原数组从大到小排序,并去重。 然后对剩下的数组进行dfs搜索。
依据是每次每种数组用多少个,从第一个开始往后,记录每一个数值使用的个数,最后依照这个使用个数的数组进行输出即可。
代码:
#include <iostream> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <algorithm> using namespace std; #define mst(a,b) memset(a,b,sizeof(a)) #define REP(a,b,c) for(int a = b; a < c; ++a) #define eps 10e-8 const int MAX_ = 10010; const int N = 100010; const int INF = 0x7fffffff; bool vis[MAX_]; int h[MAX_]; int num[MAX_]; int a[MAX_]; int dir[2] = {1,-1}; bool flag; int n, m; void dfs(int cur, int sum) { if(sum == n) { bool first = 0; REP(i, 0, m) { REP(j, 0, h[i]) { if(!first) { printf("%d", a[i]); first = 1; } else { printf("+%d", a[i]); } } } printf("\n"); flag = 1; return ; } if(cur == m) { return ; } for(int i = num[a[cur]]; i > -1; -- i) { if(i * a[cur] + sum > n)continue; h[cur] = i; dfs(cur+1,sum + i*a[cur]); } } bool cmp(const int a, const int b) { return a>b; } int main() { int T; while(scanf("%d%d", & n, & m), n||m) { flag = 0; mst(num, 0); REP(i, 0, m) { scanf("%d", &a[i]); num[a[i]] ++; } sort(a,a+m,cmp); m = unique(a,a+m) - a; printf("Sums of %d:\n", n); dfs(0, 0); if(!flag) { printf("NONE\n"); } } return 0; }