动态规划—完全背包
来源:互联网 发布:数据库备份与恢复策略 编辑:程序博客网 时间:2024/06/08 06:24
完全背包就是不限物品个数,相当于有无限个;举个栗子
有N种物品和一个容量为m的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
核心代码:dp[i][j]=max(dp[i][j],dp[i-1][j-k*c[i]]+k*w[i]);0<=k*c[i]<=v
模板:#include<bits/stdc++.h> using namespace std; const int maxn=555; int dp[maxn][111111]; int c[maxn],w[maxn]; int n,v; int main() { int i,j,k; while(~scanf("%d %d",&n,&v)) { memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) scanf("%d %d",&c[i],&w[i]); for(i=1;i<=n;i++) { for(j=0;j<=v;j++) { for(k=0;k*c[i]<=j;k++) dp[i][j]=max(dp[i][j],dp[i-1][j-k*c[i]]+k*w[i]); } } printf("%d\n",dp[n][m]); } return 0; }
转化为01背包问题求解
既然01背包问题是最基本的背包问题,那么我们可以考虑把完全背包问题转化为01背包问题来解。最简单的想法是,考虑到第i种物品最多选V/c[i]件,于是可以把第i种物品转化为V/c[i]件费用及价值均不变的物品,然后求解这个01背包问题。这样完全没有改进基本 思路的时间复杂度,但这毕竟给了我们将完全背包问题转化为01背包问题的思路:将一种物品拆成多件物品。
更高效的转化方法是:把第i种物品拆成费用为c[i]*2^k、价值为w[i]*2^k的若干件物品,其中k满足c[i]*2^k<=V
。这是二进制的思想,因为不管最优策略选几件第i种物品,总可以表示成若干个2^k件物品的和。这样把每种物品拆成O(log V/c[i])件物品,是一个很大的改进。
但我们有更优的O(VN)的算法。
O(VN)的算法
这个算法使用一维数组,先看伪代码:
for i=1..N for v=0..V f[v]=max{f[v],f[v-cost]+weight就是
f[i][v]=max{f[i-1][v],f[i][v-c[i]]+w[i]}的变形
memset(dp,0,sizeof(dp));for(i=1;i<=m;i++)for(j=c[i];j<=v;j++){//当(j=0;j<=v;j++)时下面要加if条件 //if(j>=c[i])dp[j]=max(dp[j],dp[j-c[i]]+w[i]);}
看个例题:nyoj 311完全背包初始化的细节问题
求最优解的背包问题时,有两种问法:
1)在不超过背包容量的情况下,最多能获得多少价值
2)在恰好装满背包的情况下,最多能获得多少价值
主要的区别为是否要求恰好装满背包。但这两种问法的实现方法是在初始化的时候有所不同。
1)恰好装满背包的情况:使用二维数组f[i][v]存储中间状态,其中第一维表示物品,第二维表示背包容量
初始化时,除了f[i][0] = 0(第一列)外,其他全为负无穷。
原因:初始化 f 数组就是表示:在没有任何物品可以放入背包时的合法状态。对于恰好装满背包,只有背包容量为 0(第一列),可以什么物品都不装就能装满,这种情况是合法情况,此时价值为0。其他f[0][v](第一列)是都不能装满的,此时有容量没物品。而其他位置(除去第一行和第一列的位置),我们为了在计算中比较最大值,也要初始化为负无穷。我们从程序的角度上看,我们只允许装入背包物品的序列的起始位置是从第一列开始,这些起始位置都是合法位置,且能恰好装满的情况收益均为正值,到f[N][V]终止。
注意,我们虽然是求恰好装满,还是需要枚举所有可以装入背包的物品,只要能装入,还需装入,收益有增加。只不过,由于恰好装满的物品的序列肯定是从第一列某行开始的,且之后的收益肯定是正值。对于非恰好装满的物品序列,其实位置肯定是从第一行某位置开始的,由于此时被初始化为负无穷,在和那些恰好装满物品序列带来的价值时,肯定是小的。所以,我们最后能获得最大值。
- 动态规划—完全背包
- 动态规划-----完全背包
- 完全背包---动态规划
- 【动态规划】完全背包
- 动态规划——01背包&完全背包
- POJ1384 动态规划 (完全背包)
- 完全背包问题 动态规划
- 完全背包(动态规划)
- 完全背包(动态规划)
- 动态规划-完全背包问题
- 完全背包 动态规划 模版
- 动态规划之完全背包
- 完全背包问题-动态规划
- [动态规划] 01背包与完全背包
- 【动态规划】完全背包、多重背包
- 动态规划&背包九讲&完全背包
- 动态规划-----背包问题-----01背包,完全背包,多重背包
- hiho第七周——完全背包(动态规划)
- FileUpload文件上传源码解析
- 修改apache的最大上传文件大小60
- 推荐三种超好用的div绝对居中的方法
- 浅谈X86汇编指令
- 禁止IE兼容模式
- 动态规划—完全背包
- ToolBar点击实现PopuWindow窗口效果
- Master 横扫围棋各路高手,是时候全面研究通用人工智能了!
- ubuntu 安装ssh-server时出现错误:openssh-server: Depends: openssh-client (= 1:5.3p1-3ubuntu3) but 1:5.3p1-3u
- 文章标题
- BFC原理以及外边距合并
- jQuery DOM
- SOCKET-linux中高并发socket最大连接数的优化详解
- C++11多线程std::thread的简单使用