背包3

Time Limit: 2000/1000ms (Java/Others)

Problem Description:

有n种(每一种有无数个)重量和价值分别为Wi,Vi的物品,现从这些物品中挑选出总量不超过W的物品,求所有方案中价值总和的最大值。

Input:

输入包含多组测试用例,每一例的开头为两位整数 n、W(1<=n<=10000,1<=W<=1000),接下来有 n 行,每一行有两位整数 Wi、Vi(1<=Wi<=10000,1<=Vi<=100)

Output:

输出为一行,即所有方案中价值总和的最大值。

Sample Input:

3 4
1 2
2 5
3 7
3 5
2 3
3 4
4 5

Sample Output:

10
7
解题思路:简单的完全背包。和01背包一样,dp[i][j]表示从前i种物品中挑选总重量不超过j时总价值的最大值。
易得状态转移方程:dp[i,j]=max(dp[i-1,j-k*wi]+k*vi)(0<=k*wi<=W),其中dp[i-1,j-k*wi]+k*vi表示前i-1种物品中选取若干件物品放入剩余容量为j-k*wi的背包中所能得到的最大价值加上k件第i种物品。很明显,多了一个参数k,时间复杂度变为O(nW∑(W/wi)),可知这样的时间复杂度是很大的,我们必须找到更优的办法。
因为在dp[i,j]的计算中选择k(k>=1)个物品得到的最大价值与在dp[i][j-wi](背包中已包含至少一件第i种物品)的计算中选择k-1个物品得到的最大价值是相同的,所以dp[i][j]的递推中k>=1部分的计算已经在dp[i][j-wi]的计算中完成了。那么有如下推导过程:
dp[i,j-wi]=max(dp[i-1,j],dp[i-1,(j-wi)-(k-1)*wi]+(k-1)*vi)(k>=1,dp[i-1,j]表示第i种物品一件都不选)
=max(dp[i-1,j],dp[i-1,j-k*wi]+(k-1)*vi)(k>=1,表示当前背包中至少含有一件第i种物品)
dp[i,j]=max(dp[i-1,j],dp[i-1,j-k*wi]+k*vi)(k>=1)
    =max(dp[i-1,j],dp[i,j-wi]+vi)
于是成功地把参数k给消掉了,现在的时间复杂度和01背包一样都为O(nW)。
怎么理解上面的状态转移方程呢?①如果第i件物品一件都不取,显然dp[i,j]=dp[i-1,j];②如果要取,那么当前背包中至少已含有一件第i种物品(即j至少已含有一个wi),则dp[i,j]=dp[i,j-wi]+vi。因为01背包中每个物品只有一件,在放入第i件物品时需考虑到前i-1件物品放入剩余背包容量为j-wi得到的最大价值,但是现在每个物品拥有无限件,即无需考虑前i-1个物品了,所要考虑的就是当前容量下能否再放入一件第i种物品,而dp[i,j-wi]已确保dp[i,j]中至少有一件第i种物品,所以要预留wi的背包容量再来存放一件第i种物品,这样就实现了一个物品可以取多件的操作。
同样地,完全背包空间也可以优化到O(W)。怎么实现呢?只需将01背包第二重循环正序枚举即可。为什么呢?通过模拟过程可以发现,正序使得一个物品可以被取多次。因为01背包中按照W递减来循环是为了保证第i次循环中的状态dp[i,j]是由状态dp[i-1,j-wi]递推而来,换句话说,这正是为了保证每件物品只选一次,保证在考虑“选入第i件物品”这件策略时,依据的是一个绝无已经选入第i件物品的子结果dp[i−1,j−wi]。而现在完全背包的特点恰是每种物品可选无限件,所以在考虑“加选一件第i种物品”这种策略时,却正需要一个可能已选入第i种物品的子结果dp[i,j-wi],所以就可以并且必须采用wi~W递增的顺序循环。
一维滚动数组状态转移方程:dp[j]=max(dp[j],dp[j-w[i]]+v[i])。
AC代码一:(二维数组实现)
 #include<bits/stdc++.h>
using namespace std;
int n,W,v[],w[],dp[][];
int main(){
while(cin>>n>>W){
for(int i=;i<=n;++i)cin>>w[i]>>v[i];
memset(dp,,sizeof(dp));
for(int i=;i<=n;++i){
for(int j=;j<=W;++j){
if(j<w[i])dp[i][j]=dp[i-][j];//当前容量j容纳不下一件第i种物品
else dp[i][j]=max(dp[i-][j],dp[i][j-w[i]]+v[i]);//再拿一件第i种物品和一件都不拿的情况比一下
}
}
cout<<dp[n][W]<<endl;
}
return ;
}
AC代码二:(一维数组实现)
 #include<bits/stdc++.h>
using namespace std;
int n,W,v[],w[],dp[];
int main(){
while(cin>>n>>W){
for(int i=;i<n;i++)
cin>>w[i]>>v[i];
memset(dp,,sizeof(dp));
for(int i=;i<n;++i) //种类
for(int j=w[i];j<=W;++j) //重量从小到大枚举
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
cout<<dp[W]<<endl;
}
return ;
}

ACM_完全背包的更多相关文章

  1. ACM_物品分堆(01背包)

    物品分堆 Time Limit: 2000/1000ms (Java/Others) Problem Description: 有n个物品,物品i的重量为Wi,现在想要把这个n个物品分类两堆,求最小的 ...

  2. ACM_寒冰王座(完全背包)

    寒冰王座 Time Limit: 2000/1000ms (Java/Others) Problem Description: 不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票(记住,只有一张钞票) ...

  3. nyist oj 311 全然背包 (动态规划经典题)

    全然背包 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描写叙述 直接说题意,全然背包定义有N种物品和一个容量为V的背包.每种物品都有无限件可用.第i种物品的体积是c,价值是 ...

  4. NYOJ 311 完全背包

    完全背包 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 直接说题意,完全背包定义有N种物品和一个容量为V的背包,每种物品都有无限件可用.第i种物品的体积是c,价值是 ...

  5. 【USACO 3.1】Stamps (完全背包)

    题意:给你n种价值不同的邮票,最大的不超过10000元,一次最多贴k张,求1到多少都能被表示出来?n≤50,k≤200. 题解:dp[i]表示i元最少可以用几张邮票表示,那么对于价值a的邮票,可以推出 ...

  6. HDU 3535 AreYouBusy (混合背包)

    题意:给你n组物品和自己有的价值s,每组有l个物品和有一种类型: 0:此组中最少选择一个 1:此组中最多选择一个 2:此组随便选 每种物品有两个值:是需要价值ci,可获得乐趣gi 问在满足条件的情况下 ...

  7. HDU2159 二维完全背包

    FATE Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  8. CF2.D 并查集+背包

    D. Arpa's weak amphitheater and Mehrdad's valuable Hoses time limit per test 1 second memory limit p ...

  9. UVALive 4870 Roller Coaster --01背包

    题意:过山车有n个区域,一个人有两个值F,D,在每个区域有两种选择: 1.睁眼: F += f[i], D += d[i] 2.闭眼: F = F ,     D -= K 问在D小于等于一定限度的时 ...

随机推荐

  1. windows开启远程

    windows开启远程桌面超级简单,跟linux相比太简单了. 补充:有瑕疵,应该是远程中的远程桌面属性打钩,但是W8.1没有这个选项,W7可以,其次创建一个管理员账户,身份是管理员,不是标准用户,要 ...

  2. Ubuntu 16.04在搭建Redis Cluster搭建时,使用gem install redis时出现:ERROR: While executing gem ... (Gem::FilePermissionError) You don't have write permissions for the /var/lib/gems/2.3.0 directory.

    注意:千万不要使用sudo来执行gem install redis. 解决方法: sudo apt-get update sudo apt-get install git-core curl zlib ...

  3. 详细图解mongodb 3.4.1 win7x64安装

    原文:http://www.cnblogs.com/yucongblog/p/6895983.html 详细图解,记录 win7 64 安装mongo数据库的过程.安装的版本是 MongoDB-win ...

  4. cheat sheet (小抄的意思-考试的时候,带在路上原先抄的重要的知识点)

    Cheat Sheet,这里面有个Cheat(欺骗),想当然的话,意思肯定不好.事实上,这Cheat Sheet 的原意的确也就是“小抄”的意思.所以,字典的定义是:“A piece of paper ...

  5. X-pack-6.2.4破解

    1.前言: X-pack是elasticsearch的一个扩展包,将安全,警告,监视,图形和报告功能捆绑在一个易于安装的软件包中,虽然x-pack被设计为一个无缝的工作,但是你可以轻松的启用或者关闭一 ...

  6. Photoshop制作的ico图标方法

    photoshop是打不开ico的.只是能够通过安装插件实现. 插件点击这里能够下载. 用法,解压后的插件文件 粘贴到:  (英文版路径) /program files/adobe/photoshop ...

  7. Java学习笔记----容器

    一.Java Collections框架是什么? Java Collections 框架中包括了大量集合接口以及这些接口的实现类和操作它们的算法(如:排序.查找.反转.替换.复制.取最小元素.取最大元 ...

  8. __init__、__str__、__del__方法

    1.def__init__()方法: class Cat: """定义了一个Cat类""" #初始化对象 def __init__(self ...

  9. Codeforces Beta Round #96 (Div. 1) C. Logo Turtle DP

    C. Logo Turtle   A lot of people associate Logo programming language with turtle graphics. In this c ...

  10. ZOJ3659 Conquer a New Region 并查集

    Conquer a New Region Time Limit: 5 Seconds      Memory Limit: 32768 KB The wheel of the history roll ...