F - Dividing

Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u

Submit Status

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 file describes one collection of marbles to be divided. The lines contain six non-negative integers n1 , . . . , 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 collection, 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. 卡了我有这么久了,终于弄清楚了这道题。。同时也对多重背包有了自己的理解。
多重背包就是为了解决0,1背包在面临大量数据时候的无力。
简言之,多重背包题目是每种物品的数量不止一件,而且可能出奇的多。这时候又像是完全背包,又像是01背包,当然,你完全可以照着01背包的思路写,把大量的同种物品当成一件一件的,但是结果绝对是TLE。 所以多重背包应运而生。
多重背包是这样的:循环每种物品,如果当前物品量*价值 已经大于等于 背包量,那就进行一次完全背包,(因为在有限的背包量时,完全可以把物品量看成无限多)。。。而且完全背包相较而言更为省时。
刚刚吴小珺同学还在纠结为什么这里能用完全背包,再解释一下,就是无论用完全背包还是01背包,目的都是在当前种物品里面,往背包里面塞尽可能多的量。。因此,如果此时物品量足够多,为什么不用完全背包来狠命的往包里塞东西?(怎么塞物品都还有多。。)。。。而且吴小珺同学,这个时候不要纠结能不能恰好放得下,完全背包恰好放不下,那01背包也放不下啊。。我只要求当前状态最优解即可。 ***********************紧跟上面的来讲,如果物品量*价值<背包量,这个时候就要用01背包来做了,但是要用到一点状态压缩的思想来缩小时间占用。。。。即,用每次在小于总量的情况下,分别塞 1、2、4、8.。。2^k个物品,这样就能大限度的减小时间(关于为何能用这样表示而不丢失状态,专门的资料里有讲这种状态压缩方法)。 好了,贴代码更加好讲
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int f[];
int rec[];
int main()
{
int n;
int i,j,k;
int count=;
while ()
{
int sum=;
for (i=; i<; i++)
{
scanf("%d",&rec[i]);
sum+=rec[i]*(i+);
}
if (!sum) break;
printf("Collection #%d:\n",++count);
if (sum%) //如果总量为奇数,根本就不要进行下去,不可能均分。
{
puts("Can't be divided.");
putchar('\n');
continue;
}
for (i=; i<=sum/; i++)
f[i]=;
for (i=; i<; i++)
{
if (!rec[i]) continue;
if (rec[i]*(i+)>=sum/) //如果可以完全背包,则进行完全背包
{
for (int v=i+; v<=sum/; v++)
if (f[v]<f[v-i-]+i+) f[v]=f[v-i-]+i+;
}
else
{
int cur;
for (cur=; cur<rec[i]; cur=cur*) //进行01背包
{
for (k=sum/; k>=cur*(i+); k--)
{
if (f[k]<f[k-cur*(i+)]+cur*(i+))
f[k]=f[k-cur*(i+)]+cur*(i+);
}
rec[i]-=cur;
}
for (k=sum/;k>=rec[i]*(i+);k--) //因为模拟下就知道,按上面的01背包,肯定有物品漏掉,此时再补充好漏掉的状态
{
if (f[k]<f[k-rec[i]*(i+)]+rec[i]*(i+))
f[k]=f[k-rec[i]*(i+)]+rec[i]*(i+);
}
}
} if (f[sum/]==sum/) //如果能均分,则必定成真。
puts("Can be divided.");
else
puts("Can't be divided.");
putchar('\n'); }
return ;
}
 

HDU_1059 多重背包问题的更多相关文章

  1. 多重背包问题:悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(HDU 2191)(二进制优化)

    悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 HDU 2191 一道裸的多重背包问题: #include<iostream> #include<algorithm> #i ...

  2. O(V*n)的多重背包问题

    多重背包问题: 有n件物品,第i件价值为wi,质量为vi,有c1件,问,给定容量V,求获得的最大价值. 朴素做法: 视为0,1,2,...,k种物品的分组背包 [每组只能选一个] f[i][j]=Ma ...

  3. 多重背包问题II

    多重背包问题II 总体积是m,每个小物品的体积是A[i] ,每个小物品的数量是B[i],每个小物品的价值是C[i] 求能够放入背包内的最大物品能够获得的最大价值 和上一个很类似 上一题体积就是价值,这 ...

  4. 多重背包问题的两种O(M*N)解法

    多重背包的题目很多,最著名的是poj1742楼教主的男人八题之一. poj1742:coins 有几种面值的钱币和每种的数量,问能够组成m以内的多少种钱数 这个题大家都归为多重背包问题,不过跟实际意义 ...

  5. 5. 多重背包问题 II 【用二进制优化】

    多重背包问题 II 描述 有 NN 种物品和一个容量是 VV 的背包. 第 ii 种物品最多有 sisi 件,每件体积是 vivi,价值是 wiwi. 求解将哪些物品装入背包,可使物品体积总和不超过背 ...

  6. 4. 多重背包问题 I

    多重背包问题 I 描述 有 NN 种物品和一个容量是 VV 的背包. 第 ii 种物品最多有 sisi 件,每件体积是 vivi,价值是 wiwi. 求解将哪些物品装入背包,可使物品体积总和不超过背包 ...

  7. 【动态规划/多重背包问题】POJ1014-Dividing

    多重背包问题的优化版来做,详见之前的动态规划读书笔记. dp[i][j]表示前i中数加得到j时第i种数最多剩余几个(不能加和得到i的情况下为-1)递推式为: dp[i][j]=mi(dp[i-1][j ...

  8. 51nod 多重背包问题(动态规划)

    多重背包问题 一个背包,承量有限为W,有n种物体,第i种物体,价值Vi,占用重量为 Wi,且有Ci件,选择物品若干放入背包,使得总重量不超过背包的承重.总价值最大? 输入 第1行,2个整数,N和W中间 ...

  9. poj 1742 多重背包问题 dp算法

    题意:硬币分别有 A1.....An种,每种各有C1......Cn个,问组成小于m的有多少种 思路:多重背包问题 dp[i][j]表示用前i种硬币组成j最多剩下多少个  dp=-1的表示凑不齐 dp ...

随机推荐

  1. Python 开篇

    一.Linux基础 - 计算机以及日后我们开发的程序防止的服务器的简单操作 二.Python开发 http://www.cnblogs.com/wupeiqi/articles/5433893.htm ...

  2. 装系统:Win7,机子是Dell 5460,有半高的mSATA SSD

    问题描述:Dell Vostro 5460有一个机械盘,有一个半高的mSATA SSD,现在想将系统重装到mSATA SSD上,但是机子BIOS的Boot选项没有mSATA,只有机械盘,怎么办? 解决 ...

  3. GCPC 2018

    C.Coolest Ski Route 题意:n个点,m条边组成的有向图,求任意两点之间的最长路径 dfs记忆化搜索 #include<iostream> #include<stri ...

  4. fuseki远程访问方法

    ./fuseki-server启动服务后,我们的服务只能是localhost访问,无法被其他人访问,那么 要怎么修改呢.很简单,把apche-jena-fuseki-3.10.0/run 下面的shi ...

  5. 洛谷 P1247 取火柴游戏

    题目传送门 暴力 \((\)由于我这样的初中蒟蒻不\((bu)\)喜\((hui)\)欢\((xie)\)数学证明,所以题解中的证明全是其他大佬的题解已经多次证明过的,这里就不再啰嗦了.\()\) - ...

  6. Centos 7 安装与卸载MYSQL5.7

    先介绍卸载防止重装 yum方式 查看yum是否安装过mysqlyum list installed mysql*如或显示了列表,说明系统中有MySQL yum卸载 根据列表上的名字 yum remov ...

  7. 把自己的项目发布到maven仓库并在maven和gradle中开始使用

    把自己的项目发布到maven仓库并在maven和gradle中开始使用 上一条博客中提到的日志打印项目总算是维护的差不多了, 不过现在使用它还是打成jar包放到其他项目内, 所以决定把项目传到mave ...

  8. JuJu团队11月27号工作汇报

    JuJu团队11月27号工作汇报 JuJu   Scrum 团队成员 今日工作 剩余任务 困难 于达 将真实数据处理后按矩阵读入, 以供训练使用  提供generator的接口 对julia语言还不够 ...

  9. Day 28:SAX解析原理

    SAX解析 回顾DOM解析 DOM解析原理:一次性把xml文档加载进内存,然后在内存中构建Document树. 缺点: 不适合读取大容量的xml文件,容易导致内存溢出. SAX解析原理: 加载一点,读 ...

  10. P1054 求平均值

    P1054 求平均值 转跳点: