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 just split the collection in half. But unfortunately, some of the marbles are larger, or more beautiful than others. So, Marsha and Bill start by assigning a value, a natural number between one and six, to each marble. Now they want to divide the marbles so that each of them gets the same total value. 
Unfortunately, they realize that it might be impossible to divide the
marbles in this way (even if the total value of all marbles is even).
For example, if there are one marble of value 1, one of value 3 and two
of value 4, then they cannot be split into sets
of equal value. So, they ask you to write a program that checks whether
there is a fair partition of the marbles.
 
 Input
Each line in the input describes one
collection of marbles to be divided. The lines consist of six
non-negative integers n1, n2, ..., n6, where ni is the number of marbles
of value i. So, the example from above would be described
by the input-line ``1 0 1 2 0 0''. The maximum total number of marbles
will be 20000. 
The last line of the input file will be ``0 0 0 0 0 0''; do not process this line.
 
 Output
For each colletcion, output
``Collection #k:'', where k is the number of the test case, and then
either ``Can be divided.'' or ``Can't be divided.''. 
Output a blank line after each test case.
 
 Sample Input
1 0 1 2 0 0
1 0 0 0 1 1
0 0 0 0 0 0
 Sample Output
Collection #1: Can't be divided.
Collection #2: Can be divided.
 
  题目的意思大概就是有6石头价值分别为1~6,现在给你这6种石头的个数,问你能否把它们分为价值相等的两堆。
  第一遍读完题觉得这是一个多重背包,准备模板直接过,但是看了看数据的范围,石头的个数能达到20000!铁铁的TLE。所以网上有学了一招----多重背包的二分优化。
  我们先来回顾一下,多重背包的本质还是01背包,01背包的本质是什么呢?我个人感觉就是把每种物品是否装进背包的情况遍历一遍。
  现在我们来看这样的问题,给你20个价值为1的物品,如果按照01背包的思路就要把这20个物品挨个判断是否加入背包。如果我们按照二进制的想法呢?
将这20个物品合并成1(2^0),2(2^1),4(2^2),8(2^3),5(20-1-2-4-8=5)这5个物品,只对这四个物品进行是否加入背包的判断是不是就大大减少了复杂度?现在问题转化为这两种背包是否等价?也就是用1,2,4,8,5这5个数能否组合出1~20里所有的数?  答案是显然可以的!前面2^n部分可利用二进制来表示1~15,从11到15上再加上那个5,就能表示16~20。如此,我们把个数较多的石头按2^n进行合并,最后剩下的单独一个(例如上面的5),这就是多重背包的二进制优化。
代码如下 :
 #include <bits/stdc++.h>

 using namespace std;
int num[],sum,v,cnt,i,j;
bool dp[];//dp[i]表示容量为i的背包能否装满
int main()
{
//freopen("de.txt","r",stdin);
int casenum=;
while ()
{
memset(dp,,sizeof dp);
memset(num,,sizeof num);
sum=;
for (i=;i<=;++i)
{
scanf("%d",&num[i]);
sum+=i*num[i];
}
if (sum==)
break;
printf("Collection #%d:\n",casenum++);
if (sum%)//如果所有石头总价值和为奇数肯定不能均分
{
printf("Can't be divided.\n\n");
continue;
}
else
{
v=sum/;//用总价值的一半来作为背包的容量
dp[]=;
for (i=;i<=;++i)
{
if (num[i]==)
continue;
for (j=;j<=num[i];j*=)//j来作为2^n的单位
{
cnt=i*j;
for (int k=v;k>=cnt;--k)
{
if (dp[k-cnt])//只有k-cnt的背包被装满,k的背包才能被装满
dp[k]=;
}
num[i]-=j;//分完2^n剩下的个数
}
cnt=num[i]*i;
if (cnt)
{
for (int k=v;k>=cnt;--k)
{
if (dp[k-cnt])
dp[k]=;
}
}
}
if (dp[v])//容量为v的背包能否被装满
printf("Can be divided.\n\n");
else
printf("Can't be divided.\n\n");
}
}
return ;
}
 

hdu1059&poj1014 Dividing (dp,多重背包的二分优化)的更多相关文章

  1. HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化)

    HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化) 题意分析 给出一系列的石头的数量,然后问石头能否被平分成为价值相等的2份.首先可以确定的是如果石头的价值总和为奇数的话,那 ...

  2. 硬币问题 (dp,多重背包的二分优化)

    题目描述 给你n种硬币,知道每种的面值Ai和每种的数量Ci.问能凑出多少种不大于m的面值. 输入 有多组数据,每一组第一行有两个整数 n(1≤n≤100)和m(m≤100000),第二行有2n个整数, ...

  3. poj1014 Dividing (多重背包)

    转载请注明出处:http://blog.csdn.net/u012860063 题目链接:id=1014">http://poj.org/problem?id=1014 Descrip ...

  4. CodeForces922E DP//多重背包的二进制优化

    https://cn.vjudge.net/problem/1365218/origin 题意 一条直线上有n棵树 每棵树上有ci只鸟 在一棵树底下召唤一只鸟的魔法代价是costi 每召唤一只鸟,魔法 ...

  5. POJ1014:Dividing(多重背包)

    http://poj.org/problem?id=1014 Description Marsha and Bill own a collection of marbles. They want to ...

  6. HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化)

    HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化) 题意分析 先把每种硬币按照二进制拆分好,然后做01背包即可.需要注意的是本题只需要求解可以凑出几种金钱的价格,而不需要输出种数 ...

  7. HDOJ(HDU).2191. 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活 (DP 多重背包+二进制优化)

    HDOJ(HDU).2191. 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活 (DP 多重背包+二进制优化) 题意分析 首先C表示测试数据的组数,然后给出经费的金额和大米的种类.接着是每袋大米的 ...

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

    http://acm.hdu.edu.cn/showproblem.php?pid=1059 Dividing Time Limit: 2000/1000 MS (Java/Others)    Me ...

  9. 动态规划:HDU2844-Coins(多重背包的二进制优化)

    Coins Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

随机推荐

  1. C#操作Access的查询、添加、删除、修改源程序

    C#操作Access的查询.添加.删除.修改源程序 using System; using System.Collections.Generic; using System.ComponentMode ...

  2. Jmeter 5.1 从excel读取数据执行接口自动化

    思路:数据在excel文件中进行维护,然后转换成csv格式,jme中读取数据执行: 1.将接口各数据在excel文件中进行维护,然后存为csv格式,我的数据如下: 2.jmeter脚本,配置csv文件 ...

  3. 用 Flask 来写个轻博客 (21) — 结合 reCAPTCHA 验证码实现用户注册与登录

    目录 目录 前文列表 扩展阅读 添加账户管理蓝图 新建控制器蓝图 新建表单 新建蓝图 main 的视图函数 新建模板 页面效果 前文列表 用 Flask 来写个轻博客 (1) - 创建项目 用 Fla ...

  4. 重新认识Maven

    PS:第一次接触maven大约是两年前吧,隐约记得之前都是人工寻找并下载很多jar,放在项目的lib中(表示太年轻,没有接触过Ant或者其他类似的工具,就不找别人写的比较了).懒人永远有着自己的小聪明 ...

  5. IDEA-Tomcat 运行报错

    我的问题是SDK版本不一致

  6. 将QTP运行时的错误截图上传到QC

    Class QCImageErrorCapture Sub Class_Terminate() 'Check if the current test has failed. If failed the ...

  7. Linux环境下OpenSceneGraph的安装和配置

    1.在GitHub上下载OpenSceneGrpah的源码包,地址. 2.解压缩源码包并进入源码包; 3.安装所需的依赖库: 先输入命令: sudo apt-get install openscene ...

  8. Scrapy框架: 通用爬虫之CrawlSpider

    步骤01: 创建爬虫项目 scrapy startproject quotes 步骤02: 创建爬虫模版 scrapy genspider -t quotes quotes.toscrape.com ...

  9. SPI、IIC、IIS、UART、JTAG的应用场合级区别

    SPI  SPI接口的全称是"Serial Peripheral Interface",意为串行外围接口,是Motorola首先在其MC68HCXX系列处理器上定义的. SPI接口 ...

  10. java中延迟任务的处理方式

    1.利用延迟队列 延时队列,第一他是个队列,所以具有对列功能第二就是延时,这就是延时对列,功能也就是将任务放在该延时对列中,只有到了延时时刻才能从该延时对列中获取任务否则获取不到…… 应用场景比较多, ...