现在的位置: 首页 > 综合 > 正文

hdu 1258 Sum It Up(dfs)

2017年10月18日 ⁄ 综合 ⁄ 共 1170字 ⁄ 字号 评论关闭

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

抱歉!评论已关闭.