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.
 
解题思路:用多重背包的思路来挑选若干件相同或不同的物品,最后看能否组成总价值的一半即可。
AC代码(432ms):
 #include<bits/stdc++.h>
using namespace std;
int W,tol,cas=,x[],dp[];
void ZeroOnePack(int w,int v){
for(int j=W;j>=w;--j)
dp[j]=max(dp[j],dp[j-w]+v);
}
void CompletePack(int w,int v){
for(int j=w;j<=W;++j)
dp[j]=max(dp[j],dp[j-w]+v);
}
void MultiplePack(int w,int v,int num){
if(w*num>=W)CompletePack(w,v);
else{
for(int k=;k<=num;k<<=){
ZeroOnePack(w*k,v*k);
num-=k;
}
if(num>)ZeroOnePack(w*num,v*num);
}
}
int main(){
while(~scanf("%d%d%d%d%d%d",&x[],&x[],&x[],&x[],&x[],&x[])){
tol=x[]+x[]*+x[]*+x[]*+x[]*+x[]*;
if(!tol)break;
else if(tol&)printf("Collection #%d:\nCan't be divided.\n\n",cas++);
else{
W=tol/;memset(dp,,sizeof(dp));
for(int i=;i<=;++i)
MultiplePack(i,i,x[i]);
if(dp[W]==W)printf("Collection #%d:\nCan be divided.\n\n",cas++);
else printf("Collection #%d:\nCan't be divided.\n\n",cas++);
}
}
return ;
}

AC代码二(312ms):单调队列稍微优化版。

 #include<bits/stdc++.h>
using namespace std;
int W,tol,cas=,x[],dp[];
struct node{
int k,v;
node(int x,int y):k(x),v(y){}
};
deque<node> dq;
void SingleDeque(int w,int v,int cnt){
for(int r=;r<w;++r){//r=j%w
dq.clear();
for(int t=;t*w+r<=W;++t){//t=j/w
int tmp=dp[t*w+r]-t*v;
while(!dq.empty()&&tmp>=dq.back().v)dq.pop_back();
dq.push_back(node(t,tmp));
while(!dq.empty()&&(t-cnt>dq.front().k))dq.pop_front();
dp[t*w+r]=dq.front().v+t*v;
}
}
}
int main(){
while(~scanf("%d%d%d%d%d%d",&x[],&x[],&x[],&x[],&x[],&x[])){
tol=x[]+x[]*+x[]*+x[]*+x[]*+x[]*;
if(!tol)break;
else if(tol&)printf("Collection #%d:\nCan't be divided.\n\n",cas++);
else{
W=tol/;memset(dp,,sizeof(dp));
for(int i=;i<=;++i)
SingleDeque(i,i,x[i]);
if(dp[W]==W)printf("Collection #%d:\nCan be divided.\n\n",cas++);
else printf("Collection #%d:\nCan't be divided.\n\n",cas++);
}
}
return ;
}

AC代码三(78ms):考虑多重部分和解法。dp[i][j]表示前i-1种数加和得到j时第i-1种数最多能剩余多少个(不能加和得到j的情况下为-1)。

 #include<bits/stdc++.h>
using namespace std;
int W,tol,cas=,x[],dp[];
int main(){
while(~scanf("%d%d%d%d%d%d",&x[],&x[],&x[],&x[],&x[],&x[])){
tol=x[]+x[]*+x[]*+x[]*+x[]*+x[]*;
if(!tol)break;
else if(tol&)printf("Collection #%d:\nCan't be divided.\n\n",cas++);
else{
W=tol/;memset(dp,-,sizeof(dp));dp[]=;//注意:初始化加和为0剩下的个数为0
for(int i=;i<=;++i){
for(int j=;j<=W;++j){
if(dp[j]>=)dp[j]=x[i];
else if(j<i||dp[j-i]<=)dp[j]=-;
else dp[j]=dp[j-i]-;
}
}
if(dp[W]>=)printf("Collection #%d:\nCan be divided.\n\n",cas++);
else printf("Collection #%d:\nCan't be divided.\n\n",cas++);
}
}
return ;
}

题解报告:hdu 1059 Dividing(多重背包、多重部分和问题)的更多相关文章

  1. HDU 1059 Dividing 分配(多重背包,母函数)

    题意: 两个人共同收藏了一些石头,现在要分道扬镳,得分资产了,石头具有不同的收藏价值,分别为1.2.3.4.5.6共6个价钱.问:是否能公平分配? 输入: 每行为一个测试例子,每行包括6个数字,分别对 ...

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

    Description Marsha and Bill own a collection of marbles. They want to split the collection among the ...

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

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

  4. hdu 1059 Dividing bitset 多重背包

    bitset做法 #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a ...

  5. hdu 1059 Dividing(多重背包优化)

    Dividing Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

  6. Hdu 1059 Dividing & Zoj 1149 & poj 1014 Dividing(多重背包)

    多重背包模板- #include <stdio.h> #include <string.h> int a[7]; int f[100005]; int v, k; void Z ...

  7. hdu 1059 Dividing

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

  8. HDU 1059 Dividing (dp)

    题目链接 Problem Description Marsha and Bill own a collection of marbles. They want to split the collect ...

  9. hdu 1059 Dividing 多重背包

    点击打开链接链接 Dividing Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

随机推荐

  1. 【Nginx】负载均衡

    本文介绍的负载均衡是针对的客户端请求在多个Nginx进程之间的均衡.注意与客户端请求在多个后端服务器之间的均衡相区别. 负载均衡问题的产生 在nginx中,建立连接的时候,会设计负载均衡问题.在多个子 ...

  2. elasticsarch5.4集群安装

    越来越多的企业已经采用ELK解决方案来对其公司产生的日志进行分析,笔者最近着手在生产环境部署自己的ELK stack,本文介绍ELK中elasticsearch5.2集群的实现. 一.环境准备 1.系 ...

  3. javascript是什么?

    JavaScript 是脚本语言 JavaScript 是一种轻量级的编程语言. JavaScript 是可插入 HTML 页面的编程代码. JavaScript 插入 HTML 页面后,可由全部的现 ...

  4. Hibernate学习(1)简单介绍

    1.什么是Hibernate?           首先,Hibernate是数据持久层的一个轻量级框架.数据持久层的框架有非常多比方:iBATIS,myBatis,Nhibernate,Siena等 ...

  5. 李洪强iOS开发之函数式 编程初窥

    函数式 编程初窥   最近在学习Erlang和Python.Erlang是完全的函数式编程语言,Python语言是面向对象的语言,但是它的语法引入了大量的函数式编程思想.越研究越觉得函数式的编程思路可 ...

  6. Eclipse中jvm执行库的Access restriction问题的解决方法

    今天在写代码的时候遇到了jre system libraries的訪问限制问题,该库是jvm执行的依赖库rt.jar,解决方式例如以下: 步骤: (1)项目右击.出现Build Path.点击进入Ja ...

  7. Sql数据库查询语言

    1.概述 Sql是一种面向数据库的结构化查询语言.是符合美国国家标准化组织ANSI的一种计算机标准语言. Sql具对数据库的操作有:增删改查.创建数据库.创建表.创建存储过程.创建视图等 RDBMS关 ...

  8. 树莓派 mongodb 安装&报错处理

    树莓派 mongodb 安装&报错处理 编译过的源码下载地址: http://files.cnblogs.com/files/xueshanshan/mongodb-rpi.zip addus ...

  9. arcgis 发布地图服务

    arcgis中,地图文档需要发布,才能为WEB所用. 咋发布呢? 1.在arcmap里面,点击 文件 - 共享为 - 服务 2.在弹出的对话框里选"发布服务",然后 3.这里面有点 ...

  10. 如何用DOS命令,获取一个目录下的文件数目

    发信人: GOOGOODALLS (我爱Figo), 信区: DOS 标  题: 如何用DOS命令,获取一个目录下的文件数目? 发信站: 水木社区 (Fri Mar  9 08:40:01 2007) ...