多重背包!!!(二进制优化的01背包)hdoj-2844
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define inf 0x3f3f3f3f;
using namespace std;
int dp[];
int val[];
int cnt[];
int n,m;
void comdp (int w,int v,int m) {
for (int i=w;i<=m;i++)
dp[i]=max (dp[i],dp[i-w]+v);
}
void zerodp (int w,int v,int m) {
for (int i=m;i-w>=;i--) {
dp[i]=max (dp[i],dp[i-w]+v);
}
}
int main ()
{
while (~scanf ("%d %d",&n,&m)&&(n||m)) {
for (int i=;i<=m;i++) dp[i]=-inf; dp[]=;
for (int i=;i<=n;i++)
scanf ("%d",&val[i]);
for (int i=;i<=n;i++)
scanf ("%d",&cnt[i]);
for (int i=;i<=n;i++) {
if (val[i]*cnt[i]>=m)
comdp(val[i],val[i],m); // 体积 价值 最大体积 多重背包
else {
int num=cnt[i];
for (int k=;k<=num;k*= ) {
zerodp(k*val[i],k*val[i],m); // 0-1背包
num-=k;
}
if (num) zerodp(num*val[i],num*val[i],m);
}
}
int ans=;
for (int i=;i<=m;i++) {
if (dp[i]>) ans++;
}
printf ("%d\n",ans);
}
return ;
}
二进制优化的证明
定理:一个正整数n可以被分解成1,2,4,…,2^(k-1),n-2^k+1(k是满足n-2^k+1>0的最大整数)的形式,且1~n之内的所有整数均可以唯一表示成1,2,4,…,2^(k-1),n-2^k+1中某几个数的和的形式。
证明如下:
(1) 数列1,2,4,…,2^(k-1),n-2^k+1中所有元素的和为n,所以若干元素的和的范围为:[1, n];
(2)如果正整数t<= 2^k – 1,则t一定能用1,2,4,…,2^(k-1)中某几个数的和表示,这个很容易证明:我们把t的二进制表示写出来,很明显,t可以表示成n=a0*2^0+a1*2^1+…+ak*2^(k-1),其中ak=0或者1,表示t的第ak位二进制数为0或者1.
(3)如果t>=2^k,设s=n-2^k+1,则t-s<=2^k-1,因而t-s可以表示成1,2,4,…,2^(k-1)中某几个数的和的形式,进而t可以表示成1,2,4,…,2^(k-1),s中某几个数的和(加数中一定含有s)的形式。
(证毕!)
多重背包!!!(二进制优化的01背包)hdoj-2844的更多相关文章
- HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化)
HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化) 题意分析 先把每种硬币按照二进制拆分好,然后做01背包即可.需要注意的是本题只需要求解可以凑出几种金钱的价格,而不需要输出种数 ...
- HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化)
HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化) 题意分析 给出一系列的石头的数量,然后问石头能否被平分成为价值相等的2份.首先可以确定的是如果石头的价值总和为奇数的话,那 ...
- HDOJ(HDU).2191. 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活 (DP 多重背包+二进制优化)
HDOJ(HDU).2191. 悼念512汶川大地震遇难同胞――珍惜现在,感恩生活 (DP 多重背包+二进制优化) 题意分析 首先C表示测试数据的组数,然后给出经费的金额和大米的种类.接着是每袋大米的 ...
- hdu1059 多重背包(转换为01背包二进制优化)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1059 之前写过一个多重背包二进制优化的博客,不懂请参考:http://www.cnblog ...
- poj1742(多重背包分解+01背包二进制优化)
Description People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar. ...
- hdu1059 dp(多重背包二进制优化)
hdu1059 题意,现在有价值为1.2.3.4.5.6的石头若干块,块数已知,问能否将这些石头分成两堆,且两堆价值相等. 很显然,愚蠢的我一开始并想不到什么多重背包二进制优化```因为我连听都没有听 ...
- HDU 1171 Big Event in HDU 多重背包二进制优化
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1171 Big Event in HDU Time Limit: 10000/5000 MS (Jav ...
- HDU 3591 (完全背包+二进制优化的多重背包)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3591 The trouble of Xiaoqian Time Limit: 2000/1000 M ...
- D - D 分糖果HDU - 1059(完全背包+二进制优化)
有两个小朋友想要平分一大堆糖果,但他们不知道如何平分需要你的帮助,由于没有spj我们只需回答能否平分即可. 糖果大小有6种分别是1.2.3.4.5.6,每种若干颗,现在需要知道能不能将这些糖果分成等额 ...
随机推荐
- meta 标签
<meta http-equiv="Refresh" content="5;url=http://www.w3school.com.cn" /> & ...
- C# 通过Newtonsoft.Json.dll序列化日期的处理
Newtonsoft.Json.dll提供了非常好的Json序列化和反序列化方式,但是对日期的处理却让我纠结了很久.首先定义类如下: public class Student{ public int ...
- 雷林鹏分享:Ruby 块
Ruby 块 您已经知道 Ruby 如何定义方法以及您如何调用方法.类似地,Ruby 有一个块的概念. 块由大量的代码组成. 您需要给块取个名称. 块中的代码总是包含在大括号 {} 内. 块总是从与其 ...
- Python 运算符重载
https://www.cnblogs.com/hotbaby/p/4913363.html
- pluck的返回值
前言 今天用到了laravel的pluck功能,就顺便记录下来. pluck是获取所读取的数据一列或者两列的方法. 一.获取一列代码如下: ->pluck('pic_url') ; 结果如下: ...
- Java使用POI读取和写入Excel指南
Java使用POI读取和写入Excel指南 做项目时经常有通过程序读取Excel数据,或是创建新的Excel并写入数据的需求: 网上很多经验教程里使用的POI版本都比较老了,一些API在新版里已经废弃 ...
- Nodejs AES加密
这几天被一个问题困扰着. Nodejs的AES加密和Java,C#加密出来的不一致.当然,这样就不能解密了. 纠结了许久:后来还是实在不行了,看了下源代码,要不然还得继续纠结下去. 网上说,通常的no ...
- HDOJ1003
#include<iostream> using namespace std; int main() { ],t=,m; cin >> n; while(n--) { cin ...
- Oracle 账户锁定问题解决办法
1 打开 SQL PLUS 2 登录数据库 3 输入 conn/as sysdba; 4 输入 alter user 数据库名 account unlock;
- DB2性能调优
1.更新统计信息 --更新数据库所有表统计信息 --连接到数据库(-v选项,表示要回显命令,以下同) db2 -v connect to DB_NAME --查看是否收集过统计信息,什么时候更新的 ...