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 ...
随机推荐
- 四 Hibernate的一级缓存&事务管理及其配置
持久态对象: 自动更新数据库,原理是一级缓存. 缓存:是一种优化的方式,将数据存入内存,从缓存/内存中获取,不用通过存储源 Hibernate框架中提供了优化手段:缓存,抓取策略 Hibernate中 ...
- 十九 Listener
Listener 监听器 一 监听器内部原理:其实就是接口回调 需求:A在执行循环,当循环到5的时候,通知B 事先先把某一个对象传递给A ,当A执行到5的时候,通过这个对象来调用B中的方法 但是不是直 ...
- 61 C项目------家庭收支软件
1,目标: ①模拟实现一个基于文本界面的<家庭收支软件> ②涉及知识点 局部变量和基本数据类型 循环语句 分支语句 简单的屏幕输出格式控制 2,需求说明: ①模拟实现基于文本界面的< ...
- POJ 1027:The Same Game 较(chao)为(ji)复(ma)杂(fan)的模拟
The Same Game Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5168 Accepted: 1944 Des ...
- JDK8~JDK11的新特性
#JDK 1.8 新特性接口中的静态方法 只能由接口自己调用 接口中的默认方法 可以不被覆盖 #JDK 1.9 新特性(可能在JDK8中被忽略了,没来得及加)接口可以定义私有方法,但是只能让自己调用, ...
- mysql批量插入更新操作
//添加关联赠品(确定) public function addGiveGoods($ids,$child,$parent_sku_no){ $license=new LicenseModel(); ...
- 七、Vue组件库:Element、Swiper(轮播专用组件)
一.vue的Element组件库 官网:https://element.eleme.cn/#/zh-CN 1.1安装 推荐安装方法: 首先要进入项目目录 cnpm i element-ui -S 或 ...
- MyBatis: No MyBatis mapper was found in '[xx.mapper]' package. Please check your configuration
在应用入口加入@MapperScan("com.IBM.XXXXX.dao")
- 定义一个共享数据块DB1 在DB1中定义一个数组 用程序 访问数据里面的某一个成员或者地址连续的成员
提纲 : 定义一个共享数据块 DB1 在DB1 中定义数组 用SFC21 实现 实现全部数组元素的赋一样的值 实现 给数组中的某一个元素赋值 实现 对数组中的全部元素赋值 实现将数组中的某个 或者 某 ...
- centos7安装配置supervisor守护进程
yum install Supervisor supervisord -c /etc/supervisord.conf 进入 cd /etc 目录 找到supervisord.conf 配置文件 和 ...