链接:

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; }

 

posted on 2015-08-17 18:57  栀蓝  阅读(210)  评论(0编辑  收藏  举报

levels of contents