你的背包_多重!
来源:互联网 发布:matlab数据挖掘教程 编辑:程序博客网 时间:2024/05/15 21:03
P01:01背包问题
有N种物品和一个容量为V的背包。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包的容量,且价值总和最大。每种物品仅有一件。
P02:完全背包问题
有N种物品和一个容量为V的背包。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包的容量,且价值总和最大。每种物品都有无限件。
P03:多重背包问题
有N种物品和一个容量为V的背包。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包的容量,且价值总和最大。每种物品最多有n[i]件。
P03:
多重背包与完全背包类似。基本的算法只需要修改完全背包的方程即可。多重背包中,对于第i种物品有n[i]+1种策略,取0件,取1件,···,取n[i]件。同样定义dp[i][j],则可得出状态转移方程:
dp[i][j] = max { dp[i-1][j-k*c[i]] + k*w[i] | 0<=k<=n[i] }.
复杂度为O(V*∑n[i])。
/****author :Or_me **╭︿︿︿╮{/ A C /} ( (OO) ) ︶︶︶ ** ****HDU_2191题**** 2014 年 7月 30日****/#include <cmath>#include <queue>#include <stack>#include <vector>#include <cstdio>#include <string>#include <cctype>#include <climits>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;int p[500],h[500],c[500],dp[500];int main(){ int C; scanf("%d",&C); while (C--) { int n,m; scanf("%d%d",&n,&m); for (int i=0;i<m;i++) scanf("%d%d%d",&p[i],&h[i],&c[i]);//价格,重量,袋数 memset(dp,0,500*4); for (int i=0;i<m;i++) for (int k=1;k<=c[i];k++) for (int j=n;j>=p[i];j--) dp[j]=max(dp[j],dp[j-p[i]]+h[i]); printf("%d\n",dp[n]); } return 0;}然后就是优化问题,考虑二进制的思想。考虑把第i种物品换成若干件物品,使得原问题中第i种物品可取的每种策略,取0件,取1件,···取n[i]件,均能等价于取若干件代换后的物品,而且取超过n[i]件的策略不会出现。
将第i种物品分成若干件物品,其中每件物品有一个系数,这件物品的费用和价值均是原来的费用和价值乘以这个系数。使这些系数分别为1,2,4,···,2^(k-1),n[i]-2^k+1,且k是满足n[i]-2^k+1>0的最大整数。例,当n[i]=13时,k=3,所以就将这种物品分成系数分别为1,2,4,6的四件物品。
分成的这几件物品的系数和为n[i],这就表明不可能取多于n[i]件的第i种物品。另外,这种方法也能保证对于0...n[i]间的每一个整数,均可以用若干个系数的和来表示,这个证明可以分0...2^(k-1)和2^k...n[i]两端来分别讨论。这样就将第i种物品分成了O(log(n[i]))种物品,将复杂度优化到O(V*∑long(n[i]))的01背包问题。
/****author :Or_me **╭︿︿︿╮{/ A C /} ( (OO) ) ︶︶︶ ** ****HDU_2191题**** 2014 年 7月 30日****/#include <cmath>#include <queue>#include <stack>#include <vector>#include <cstdio>#include <string>#include <cctype>#include <climits>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;int p[500],h[500],c[500],dp[500];void ZeroPack(int x,int y,int v)//价值、花费、容量{for (int i=v;i>=y;i--){dp[i]=max(dp[i],dp[i-y]+x);}}void CompletePack(int x,int y,int v)//价值、花费、容量{for (int i=y;i<=v;i++){dp[i]=max(dp[i],dp[i-y]+x);}}int main(){ int T; scanf("%d",&T); while (T--) { int n,m; scanf("%d%d",&n,&m); memset(dp,0,sizeof(dp)); for (int i=0;i<m;i++) { scanf("%d%d%d",&p[i],&h[i],&c[i]);//价格,重量,袋数 } for (int i=0;i<m;i++) { if (c[i]*p[i]>=n) { CompletePack(h[i],p[i],n); } else { int k=1; while (k<c[i]) { ZeroPack(k*h[i],k*p[i],n); c[i]-=k; k*=2; } ZeroPack(c[i]*h[i],p[i]*c[i],n); } } printf("%d\n",dp[n]); } return 0;}
- 你的背包_多重!
- 多重背包的优化
- hdu 2191多重背包_二进制优化
- 动态规划8_多重背包
- poj1276_多重背包_二进制优化
- 背包问题九讲笔记_多重背包
- 背包问题九讲笔记_多重背包
- 混合背包+多重背包的二进制优化
- 背包问题:多重背包的优化
- 多重背包问题的应用
- 多重背包的可行性问题
- 多重背包的二进制转化
- 多重背包的一个解法
- 多重背包的二进制优化
- 多重背包的二进制优化
- 多重背包的二进制优化
- 多重背包的二进制优化
- 01背包完全背包多重背包的概念
- iOS音频流播放、后台播放、远程控制、锁屏封面
- Memcached的配置
- hdoj.2027 统计元音 20140726
- linux下编译windows版android sdk
- Android异步消息处理线程之----Looper+MessageQueue+Handler
- 你的背包_多重!
- hdu4893Wow! Such Sequence! (线段树)
- 阿城市哪有小姐妹
- jBPM4.4:在看开发指南之前总结一下
- 尚志市哪有小姐妹
- Redis的配置
- 网站编辑发文章SEO规范
- Android中activity的生命周期以及使用场景
- 双城市哪有小姐妹