poj 1014 Dividing (搜索:DFS)

感觉就是一个爆搜的题目,但是却被列为DP了...

令flag[i] == true表示i这个数据可以分配成功

则我们只需依次遍历直到出现flag[sum/2]==true

或已遍历完小于sum/2的部分但是没有flag[sum/2]==true

这题有个地方比较坑就是题目中说了所有堆数之和最大为20000

但是应该指的是每堆最大20000,害的re了好几次。。。

0ms代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 120010
using namespace std;

int a[10];
bool flag[MAXN];

bool dfs(int sum) {
    int tmp, maxv;
    maxv = 0;
    if(sum % 2)
        return false;

    sum >>= 1;
    memset(flag, false, sizeof(flag));
    flag[0] = true;

    for(int i=1; i<=6; ++i) {
        if(a[i] > 0) {
            for(int j=maxv; j>=0; --j) {//这里要倒着搜,否则一组数据会重复使用,原因是不让后面的flag[tmp]对当前循环产生影响
                if(flag[j]) {
                    for(int k=1; k<=a[i]; ++k) {
                        tmp = j+k*i;
                        if(tmp == sum)
                            return true;
                        if(tmp>(sum) || flag[tmp])
                            break;
                        flag[tmp] = true;
                    }
                }
            }
        }
        maxv += a[i]*i;
        maxv = max(sum, maxv);
    }
    return false;
}

int main(void) {
    int sum, cas = 1;
    bool tmp;
    while(scanf("%d", &a[1]) != EOF) {
        sum = a[1];
        for(int i=2; i<=6; ++i) {
            scanf("%d", &a[i]);
            sum += a[i]*i;
        }
        if(sum == 0)
            break;
        tmp = dfs(sum);
        printf("Collection #%d:\n", cas++);
        if(sum < 0)
            tmp = false;
        if(tmp)
            printf("Can be divided.\n\n");
        else printf("Can't be divided.\n\n");

    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值