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

 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。 这个可列举一些小的数据后计算就能验证。

时间: 2024-10-13 01:11:48

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

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

题目: 链接:点击打开链接 题意: 判断是否能够平分弹珠. 算法: 多重背包. 思路: 模板...dp[i]中i表示花费.. 代码: #include<iostream> #include<cstdio> #include<cstring> using namespace std; int n[7]; int dp[120010]; int V; void bag_01(int c,int w)//01背包 { for(int i=V; i>=c; i--) dp

HDU 3591 The trouble of Xiaoqian(多重背包+01背包)

HDU 3591 The trouble of Xiaoqian(多重背包+01背包) http://acm.hdu.edu.cn/showproblem.php?pid=3591 题意: 有一个具有n种货币的货币系统, 每种货币的面值为val[i]. 现在小杰手上拿着num[1],num[2],-num[n]个第1种,第2种-第n种货币去买价值为T(T<=20000)的商品, 他给售货员总价值>=T的货币,然后售货员(可能,如果小杰给的钱>T, 那肯定找钱)找钱给他. 售货员每次总是用

hdu 2082 找单词(母函数|多重背包)

http://acm.hdu.edu.cn/showproblem.php?pid=2082 每一个字母的价值固定,但数目不定.所以每个字母对应的表达式也不同,若第i个字母的个数为a[i],价值为i,那么它的母函数为(1+x^i+x^(2i)+.....+x^(a[i]*b[i])).那么将i属于[1,26]的母函数相乘得到的x^m(1<=m<=50)的系数相加就是答案. #include <stdio.h> #include <iostream> #include &

hdu(1059) Dividing(多重背包)

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

ACM学习历程—HDU 1059 Dividing(dp &amp;&amp; 多重背包)

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 just spl

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

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

(母函数经典题 与2082类似)hdu 1059 Dividing

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