hdoj 1059 Dividing 【多重背包】||【优化母函数】

题意:每一种弹珠(marble)的都有各自的价值,第一种为1, 第二种为2,。。,给出你每种弹珠的数量,求能不能将价值总和均分。

策略:rt;

这道题比赛的时候没有想到用母函数,就用了多重背包来解,之后递交的时候时间居然超600ms,我再一看递交排行都是0ms(⊙﹏⊙b汗)。看到讨论区有人说母函数也可以,于是就写了个普通的,可惜TL了。果然还是需要优化啊。。。于是游来游去果然0ms(O(∩_∩)O哈哈哈~)。

说一下0秒的思路,因为只是问能不能均分,所以我们没有必要找种类数,找到了就定义为1好了,而且,从目标开始找往下找也会增加速度。不多说,直接上代码。

代码1(多重背包)(609ms):

#include <stdio.h>
#include <string.h>
int s[6];
int dp[120050];
int main()
{
    int v = 1;
    while(scanf("%d%d%d%d%d%d", &s[0], &s[1], &s[2], &s[3], &s[4], &s[5]) == 6){
        int sum = 0, c[20000], w[20000], i, j;
        for(i = 0; i < 6; i ++){
            sum += s[i]*(i+1);
        }
        if(sum == 0) break;
        printf("Collection #%d:\n", v++);
        if(sum%2){
            printf("Can't be divided.\n\n");
            continue;
        }
        else{
            sum/=2;
            for(i = 1; i <= sum; i++) dp[i] = -120050;
            dp[0] = 0;
            int tot = 0;
            for(i = 0; i < 6; i ++){
                int l = 1;
                while(s[i] >= l){
                    c[tot] = l*(i+1);
                    w[tot++] = l*(i+1);
                    s[i] -= l;
                    l<<=1;
                }
                if(s[i]){
                    c[tot] = s[i]*(i+1);
                    w[tot++] = s[i]*(i+1);
                }
            }
            for(i = 0; i < tot; i ++){
                for(j = sum; j >= c[i]; j --){
                    if(dp[j] < dp[j-c[i]]+w[i]) dp[j] = dp[j-c[i]]+w[i];// printf("%d..%d\n", dp[j], j);
                }
            }
            if(dp[sum] > 0)  printf("Can be divided.\n");
            else  printf("Can't be divided.\n");
            printf("\n");
        }
    }
}

代码2(母函数优化)0ms:

#include <stdio.h>
#include <string.h>
int c1[120000];
int main()
{
    int s[7], i, j, k, v = 1;
    while(1){
        int sum = 0;
        for(i = 1; i <= 6; i ++){
            scanf("%d", &s[i]);
            sum += (s[i]%60)*i;
        }
        if(sum == 0) break;
        printf("Collection #%d:\n", v++);
        if(sum & 1){
        printf("Can't be divided.\n\n"); continue;
        }
        sum >>=1;
        memset(c1, 0, sizeof(c1));
        for(i = 0; i <= sum&&i <= s[i]; i ++){  //第一种弹珠
            c1[i] = 1;
        }
        for(i = 2; i <= 6; i ++){  //2~6
            if(s[i] == 0) continue;  //如果该种弹珠数目为0,不没有必要往下了,去掉这一句,要15ms
            for(j = sum; j >= 0; j --){//从头往下找
                if(c1[j] == 0) continue;  //如果这个不能达到,那么由他组成的也不能达到所以就不用找了
                for(k = i; k + j <= sum&&k <= s[i]*i; k+=i){
                    c1[j+k] = 1;
                }
            }
        if(c1[sum]) printf("Can be divided.\n\n");
        else printf("Can't be divided.\n\n");
    }
    return 0;
}

代码3(母函数)31ms:(不懂为什么,以后学到了类似的知识点再来看)

#include <stdio.h>
#include <string.h>
int c1[120000], c2[120000];
int main()
{
    int s[7], i, j, k, v = 1;
    while(1){
        int sum = 0;
        for(i = 1; i <= 6; i ++){
            scanf("%d", &s[i]);
            sum += (s[i]%60)*i;  //与传统的其他没区别,只有这一点s[i]%60有区别,难道说是有规律吗?
        }
        if(sum == 0) break;
        printf("Collection #%d:\n", v++);
        if(sum & 1){
        printf("Can't be divided.\n\n"); continue;
        }
        sum >>=1;
        memset(c1, 0, sizeof(c1));
        memset(c2, 0, sizeof(c2));
        c1[0] = 1;
        for(i = 1; i <= sum&&i <= s[i]; i ++){
            c1[i] = 1;
        }
        for(i = 2; i <= 6; i ++){
            if(s[i] == 0) continue;
            for(j = 0; j <= sum; j ++){
                for(k = 0; k + j <= sum&&k <= s[i]*i; k+=i){
                    c2[j+k] += c1[j];
                }
            }
            for(j = 0; j <= sum; j ++){
                c1[j] = c2[j];
                c2[j] = 0;
            }
        }
        if(c1[sum]) printf("Can be divided.\n\n");
        else printf("Can't be divided.\n\n");
    }
    return 0;
}

题目链接:点击打开链接

hdoj 1059 Dividing 【多重背包】||【优化母函数】

时间: 2024-08-27 00:44:46

hdoj 1059 Dividing 【多重背包】||【优化母函数】的相关文章

hdu 1059 Dividing(多重背包优化)

Dividing Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 20635    Accepted Submission(s): 5813 Problem Description Marsha and Bill own a collection of marbles. They want to split the collection

HDU 1059 Dividing(多重背包)

HDU 1059 Dividing(多重背包) http://acm.hdu.edu.cn/showproblem.php?pid=1059 题意: 现在有价值为1,2,3,4,5,6的6种物品, 它们的数量为num[i]( 1<=i<=6 )个. 现在要问的是能否把所有的的物品分成两份且这两份物品的价值总和相同 ? 分析: 首先我们求出所有物品的价值和sum_val, 如果sum_val是奇数, 那么明显不能分. 那么sum_val为偶时, 我们令m=sum_val/2. 我能只要看看从所有

hdu(1059) Dividing(多重背包)

题意:输入六个数,价值分别为1——6,输入的数代表该价值的物品的个数:求能否平均分. key:如果奇数肯定不能分,直接输出答案.偶数的话,就是多重背包问题. 试过两种做法,第一种是背包九讲的二进制优化,写三个函数,分别是bag01, bagall, bagmulti~第二种是直接多重背包,但很可能tle,这题我交的就是tle了~ #include <iostream> #include <algorithm> #include <string.h> #include &

POJ 1014 / HDU 1059 Dividing 多重背包+二进制分解

Problem Description Marsha and Bill own a collection of marbles. They want to split the collection among themselves so that both receive an equal share of the marbles. This would be easy if all the marbles had the same value, because then they could

POJ 1014 Dividing (多重背包)

Dividing Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 58921   Accepted: 15200 Description Marsha and Bill own a collection of marbles. They want to split the collection among themselves so that both receive an equal share of the marbl

HDU 1059(多重背包加二进制优化)

http://acm.hdu.edu.cn/showproblem.php?pid=1059 Dividing Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 29901    Accepted Submission(s): 8501 Problem Description Marsha and Bill own a collection

poj1014+hdu1059--A - Dividing(多重背包,二进制优化)

A - Dividing Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description Marsha and Bill own a collection of marbles. They want to split the collection among themselves so that both receive an equal share of

【背包专题】G - Dividing hdu 1059【多重背包】

Marsha and Bill own a collection of marbles. They want to split the collection among themselves so that both receive an equal share of the marbles. This would be easy if all the marbles had the same value, because then they could just split the colle

多重背包优化

题目: https://www.acwing.com/problem/content/6/ 有 N 种物品和一个容量是 V 的背包. 第 ii 种物品最多有 si 件,每件体积是 vi,价值是 wi. 求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大.输出最大价值. 输入格式 第一行两个整数,N,V (0<N≤1000(0<N≤1000, 0<V≤20000),用空格隔开,分别表示物品种数和背包容积. 接下来有 N 行,每行三个整数 vi,wi,si,用空格隔开,分