hdu 1258 Sum It Up(dfs)

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章