码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1059 Dividing 分配(AC代码)多重背包的变形

时间:2015-01-23 21:27:27      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:

 

技术分享
 1 #include <iostream>
 2 using namespace std;
 3 int num[6];
 4 int dp[200];
 5 bool divide(int sum)
 6 {
 7     int k,i,j;
 8     for(i=0;i<6;i++)
 9         for(k=0;k<num[i];k++)
10             for(j=sum;j>i;j--)
11                 if(dp[j-(i+1)]+(i+1)>dp[j])
12                 dp[j]=dp[j-(i+1)]+(i+1);
13     if(dp[sum]==sum)
14         return true;
15     else
16         return false;
17 }
18 int main()
19 {
20     int i,n=0,sum;
21     while(1)
22     {
23         for(i=0,sum=0;i<6;i++)
24         {
25             scanf("%d",&num[i]);
26             num[i]%=8;
27             sum+=num[i]*(i+1);    //所有石头的价值总和    
28         }
29         if(!num[0]&&!num[1]&&!num[2]&&!num[3]&&!num[4]&&!num[5])    return 0;    //全0就退出        
30         if(sum%2!=0)    //价值的总和不能被被2整除的话就肯定分不了
31         {
32             printf("Collection #%d:\nCan‘t be divided.\n\n",++n);
33             continue;
34         }
35         else sum>>=1;    //可以分的话,总和得减半
36         memset(dp,0,sizeof(int)*(sum+1));    //清内存
37         if(divide(sum)==true)
38             printf("Collection #%d:\nCan be divided.\n\n",++n);
39         else
40             printf("Collection #%d:\nCan‘t be divided.\n\n",++n);
41     }
42     return 0;
43 }
1059

题意:两个人共同收藏了一些石头,现在要分道扬镳,得分资产了,石头具有不同的收藏价值,分别为1、2、3、4、5、6共6个价钱。问:是否能公平分配?

输入:每行为一个测试例子,每行包括6个数字,分别对应6种价钱的石头数目,比如101200代表价值为1的石头有1个,价值为2的石头有0个....价值为4的石头有2个。他们具有的石头数量的上限为2万个。

输出:见题目吧。

 

思路:想用多重背包的方式解决,也想转01背包比较简单。直接转01背包会超时,得想办法。可以用多重背包的方法,用二进制来减少复杂度,应该可行。我用的是偷懒的办法,将数据都减小,比如某个价值的石头有1千个,是偶数,那就可以直接分掉,每人500啦,但是可能会有奇数个的情况,所以不能单独将某价值的石头一次性分完。那么留多少合适?我觉得留4合适,但是实际上留了8个以下才能AC。

出现下面情况说明了不能将某个价值的石头总数mod2:

价值:1 2 3 4 5 6

数量:1 0 8 0 1 0

解释:假如%2的话,价值为3的石头就变为0个,剩下两个石头,价值分别为1和5,分不了!

所以余数必须大于2,测试了一下,6不行,8以上的偶数就行了。

现在,数据的大小降下来了,转成01背包就简单多了。将剩下的所有石头的的价值的一半假设为背包的容量,将石头的体积设为等价于其价值大小。什么意思呢?

举个例子:

价值:1 2 3 4 5 6

数量:1 0 2 0 1 0

体积:1 2 3 4 5 6

假设这是数值大小降低后的结果,一眼可以看出1+5=3*2,可以公平分配,所有石头的总价值为12,假设其中一个人是我,那么我必须分配到价值为6的石头才是公平的,不用管到底分得1块还是2块石头。而其价值与体积已经假设是相等的,那么设我的背包大小为6,我想从这些石头(4块)中挑出一些石头,使我的背包装满,只要能刚好装满,证明能公平分配,即dp[x]=x。 这个可列举一些小的数据后计算就能验证。

 

HDU 1059 Dividing 分配(AC代码)多重背包的变形

标签:

原文地址:http://www.cnblogs.com/xcw0754/p/4245027.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!