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 ...
随机推荐
- SciPy 教程
章节 SciPy 介绍 SciPy 安装 SciPy 基础功能 SciPy 特殊函数 SciPy k均值聚类 SciPy 常量 SciPy fftpack(傅里叶变换) SciPy 积分 SciPy ...
- node批量修改文件名称
let fs = require('fs');//引用文件系统模块 let PATH = `./app_zijietiaodong/`;//当前文件夹 let ext = { readFileList ...
- 初学微信小程序——配置问题(1)
一.注册: 微信小程序账号注册:登录https://mp.weixin.qq.com 点击“立即注册”->”小程序” 注册完成后,下载微信小程序开发者工具: 依次点击:“首页”->“文档 ...
- 第1节 HUE:14、15、16、hue与hdfs、yarn集群、hive、impala、mysql的整合
3.hue与其他框架的集成 3.1.hue与hadoop的HDFS以及yarn集成 第一步:更改所有hadoop节点的core-site.xml配置 记得更改完core-site.xml之后一定要重启 ...
- 富文本API
这个笔记来自网络资料的总结 简书大佬三省吾身_9862 tuobaye个人博客 富文本有相关3个API和一个新属性 var selection = window.getSelection(); var ...
- 025、MySQL字符串大小写转化函数,文本转化大写,文本转化小写
#变大写 SELECT UPPER('abcdABCD123a'); #ABCDABCD123A SELECT UCASE('abcdABCD123a'); #ABCDABCD123A #变小写 SE ...
- ACM-吴奶奶买鱼
题目描述:吴奶奶买鱼 吴奶奶有个可爱的外孙女——琪琪,她很喜欢小动物,尤其喜欢养鱼.为了让小孙女养到漂亮的小鱼,吴奶奶一大早就到花鸟鱼虫市场买鱼.这个市场可真大,里面有各种各样的宠物,就连宠物鱼都 ...
- P1050 螺旋矩阵
P1050 螺旋矩阵 转跳点:
- 快速进阶Vue3.0
在2019.10.5日发布了Vue3.0预览版源码,但是预计最早需要等到 2020 年第一季度才有可能发布 3.0 正式版. 可以直接看 github源码. 新版Vue 3.0计划并已实现的主要架构改 ...
- Java笔记: 继承成员覆盖和隐藏
在扩展类时,既可以向类中添加新的成员,也可以重新定义现有的成员.重定义现有成员的具体效果取决于成员的类型.本文不会详细的介绍概念,只简要总结覆盖(overriding,也叫重写)和隐藏(hiding) ...