多重背包!!!(二进制优化的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,每种若干颗,现在需要知道能不能将这些糖果分成等额 ...
随机推荐
- SSH Secure Shell Client--- the host may be dow
the host may be down,or there may be a problem with the network connection. Sometimes such problems ...
- 16 Managing Undo
16 Managing Undo 从Oracle11g开始,在默认安装中oracle会自动管理undo, 典型安装中不需要DBA介入配置,然而,如果选择了flash back特性,你就需要进行一些un ...
- 『科学计算_理论』优化算法:梯度下降法&牛顿法
梯度下降法 梯度下降法用来求解目标函数的极值.这个极值是给定模型给定数据之后在参数空间中搜索找到的.迭代过程为: 可以看出,梯度下降法更新参数的方式为目标函数在当前参数取值下的梯度值,前面再加上一个步 ...
- Oracle 小函数的使用
1.Oracle 正则表达式 经常会有一种需求是查询某个字符在字符串中的数量,可以使用正则表达式regexp_count函数 比如 SELECT regexp_count('0,1,1',',') f ...
- EBS标准的查看供应商地点
VO数据源:oracle.apps.pos.supplier.server.SitesVO SELECT pvsa.address_style, hzl.language, pvsa.province ...
- 使用scrapy-redis构建简单的分布式爬虫
前言 scrapy是python界出名的一个爬虫框架.Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中. 虽然scr ...
- MongoDB中_id(ObjectId)生成
MongoDB 中我们经常会接触到一个自动生成的字段:"_id",类型为ObjectId. 之前我们使用MySQL等关系型数据库时,主键都是设置成自增的.但在分布式环境下,这种方法 ...
- 练习vue(用户管理)1
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- vue 表格导出excel
首先要install两个依赖, 1 npm install -S file-saver xlsx 2 npm install -D script-loader 在项目src目录下新建一个文件夹ven ...
- git 添加review的相关操作
git主机上涉及到的操作: 185 git branch 186 git pull 187 git branch 188 git checkout -b wangcheng 189 git log 1 ...