[多重背包+二进制优化]HDU1059 Dividing

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[多重背包+二进制优化]HDU1059 Dividing相关的知识,希望对你有一定的参考价值。

题目链接

题目大意:

两个人要把一堆宝珠,在不能切割的情况下按照价值平分,他们把宝珠分成6种价值,每种价值的宝珠n个。 n<=200000

思考:

首先如果加和下来的价值是一个偶数 那么还分毛啊,直接gg.

之后多重背包二进制优化 转换为 01背包。

我们可以把价值 同时当做宝珠的空间和价值。

那么我们现在要求的是 在 空间为一半的情况下,能否找到价值为 一半的情况。

 

技术分享
 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 int dp[200005],n[7],V[105],W[100];
 5 
 6 int main(){
 7     int k=0;
 8     while(scanf("%d%d%d%d%d%d",&n[1],&n[2],&n[3],&n[4],&n[5],&n[6])!=EOF && (n[1]||n[2]||n[3]||n[4]||n[5]||n[6])){
 9         printf("Collection #%d:\n",++k);
10         int i,j,sum=0,mid;
11         for(i=1;i<=6;i++) sum+=i*n[i];
12         if(sum%2){
13             printf("Can‘t be divided.\n\n");
14             continue;
15         }
16         else mid = sum/2;
17         memset(dp,0,sizeof(dp));  //切记不要忘了初始化 
18         int count=0,temp,flag=1;
19         //这块是二进制优化 
20         for(i=1;i<=6;i++){
21             temp=1;
22             while(n[i]>=temp){
23                 V[++count]=i*temp;
24                 W[count]=i*temp;
25                 n[i]-=temp;
26                 temp*=2;
27             }
28             if(n[i]>0){
29                 V[++count]=i*n[i];
30                 W[count]=i*n[i];
31             }
32         }
33         //上面是二进制优化 
34         for(int i=1;i<=count && flag;i++)
35             for(int j=mid;j>=V[i] && flag;j--){
36                 dp[j] = std::max(dp[j],dp[j-V[i]]+W[i]);
37                 if(dp[j]==mid){   
38                     printf("Can be divided.\n\n");
39                     flag=0;
40                 }
41             }
42         if(flag){
43             printf("Can‘t be divided.\n\n");
44         }
45     }
46     return 0;
47 }
代码实现

 

以上是关于[多重背包+二进制优化]HDU1059 Dividing的主要内容,如果未能解决你的问题,请参考以下文章

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

hdu1059(背包dp二进制优化)

HDU 1059 Dividing(多重背包)

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

分弹珠(动态规划+多重背包)- HDU 1059

hdu 1059 Dividing bitset 多重背包