小記:起初以爲是一道非常水的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;
}