HDU_1059 多重背包问题
Description
Input
The last line of the input file will be "0 0 0 0 0 0"; do not process this line.
Output
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 多重背包问题的更多相关文章
- 多重背包问题:悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(HDU 2191)(二进制优化)
悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 HDU 2191 一道裸的多重背包问题: #include<iostream> #include<algorithm> #i ...
- O(V*n)的多重背包问题
多重背包问题: 有n件物品,第i件价值为wi,质量为vi,有c1件,问,给定容量V,求获得的最大价值. 朴素做法: 视为0,1,2,...,k种物品的分组背包 [每组只能选一个] f[i][j]=Ma ...
- 多重背包问题II
多重背包问题II 总体积是m,每个小物品的体积是A[i] ,每个小物品的数量是B[i],每个小物品的价值是C[i] 求能够放入背包内的最大物品能够获得的最大价值 和上一个很类似 上一题体积就是价值,这 ...
- 多重背包问题的两种O(M*N)解法
多重背包的题目很多,最著名的是poj1742楼教主的男人八题之一. poj1742:coins 有几种面值的钱币和每种的数量,问能够组成m以内的多少种钱数 这个题大家都归为多重背包问题,不过跟实际意义 ...
- 5. 多重背包问题 II 【用二进制优化】
多重背包问题 II 描述 有 NN 种物品和一个容量是 VV 的背包. 第 ii 种物品最多有 sisi 件,每件体积是 vivi,价值是 wiwi. 求解将哪些物品装入背包,可使物品体积总和不超过背 ...
- 4. 多重背包问题 I
多重背包问题 I 描述 有 NN 种物品和一个容量是 VV 的背包. 第 ii 种物品最多有 sisi 件,每件体积是 vivi,价值是 wiwi. 求解将哪些物品装入背包,可使物品体积总和不超过背包 ...
- 【动态规划/多重背包问题】POJ1014-Dividing
多重背包问题的优化版来做,详见之前的动态规划读书笔记. dp[i][j]表示前i中数加得到j时第i种数最多剩余几个(不能加和得到i的情况下为-1)递推式为: dp[i][j]=mi(dp[i-1][j ...
- 51nod 多重背包问题(动态规划)
多重背包问题 一个背包,承量有限为W,有n种物体,第i种物体,价值Vi,占用重量为 Wi,且有Ci件,选择物品若干放入背包,使得总重量不超过背包的承重.总价值最大? 输入 第1行,2个整数,N和W中间 ...
- poj 1742 多重背包问题 dp算法
题意:硬币分别有 A1.....An种,每种各有C1......Cn个,问组成小于m的有多少种 思路:多重背包问题 dp[i][j]表示用前i种硬币组成j最多剩下多少个 dp=-1的表示凑不齐 dp ...
随机推荐
- 动态、指针field-symbols初探
DATA: BEGIN OF STRUC, COMP1 VALUE ', COMP2 VALUE ', COMP3 TYPE STRING VALUE 'bruce king', END OF STR ...
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 辅助类:清除浮动1
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- java 十大经典排序算法
十大排序算法可以说是每个程序员都必须得掌握的了,花了一天的时间把代码实现且整理了一下,为了方便大家学习,我把它整理成一篇文章,每种算法会有简单的算法思想描述,为了方便大家理解,我还找来了动图演示:这还 ...
- 【LeetCode】加油站
[问题]在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升. 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升.你从其中 ...
- ubuntu16下安装mongodb 3.6
1.安装MongoDB社区版 # 1. 导入MongoDB public GPG Key sudo apt-key adv --keyserver hkp://keyserver.ubuntu ...
- jenkins#构建并部署springboot的jar包
0. 前提是有一个可以用的没有问题的Jenkins环境,这是基础 1. 安装publish over ssh 插件,(如果网速太慢,请去github 克隆代码,然后自己构建,然后上传安装此插件) 2. ...
- jq插件和jq
封装一个jq (function(win) { var jQuery = function(selecter) { this.version = '1.0.1'; //版本号 this.selecte ...
- 026、MySQL取字符串左边,取字符串右边,取字符串中间,取文本开始位置
#取文本左边 ); #田 ); #田攀 ); #田攀5 #取文本右边 ); # ); # ); #攀52 #取文本中间 '); #田攀 '); #攀5 #从字符串s中获取s1的开始位置 不忘初心,如果 ...
- JS在不改变原数组的情况下复制一个新的数组
var a={1,2,3,4} var data= JSON.parse(JSON.stringify(a[0])) a.push(data) a[4]=5 这样就不会改变原数组a的数据
- Maven的原理和使用
一.Maven能做什么 1.假设我们有10个项目,都需要引入spring core模块,那么需要十份重复的Spring Core.jar和commons-logging.jar 使用Maven:mav ...