0-1背包(动态规划)
2016-04-29 08:16
281 查看
题意:
有N件物品和一个容量为V的背包。第i件物品的体积是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。
基本思路
这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:
f[i][v] = max{f[i-1][v],f[i-1][v-c[i]]+w[i]}。
这个方程非常重要,基本上所有跟背包问题相关的问题的方程都是由它衍生出来的。所以有必要将它详细解释一下:将前i件物品放入容量为v的背包中这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只涉及前i-1件物品的问题。
如果不放第i件物品,那么问题就转化为前i-1件物品放入容量为v的背包中,此时能获得的价值为f[i-1][v];
如果放第i件物品,那么问题就转化为前i-1件物品放入剩下的容量为v-c[i]的背包中,此时能获得的最大价值就是:f[i-1][v-c[i]]+w[i]。
代码:
有N件物品和一个容量为V的背包。第i件物品的体积是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。
基本思路
这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:
f[i][v] = max{f[i-1][v],f[i-1][v-c[i]]+w[i]}。
这个方程非常重要,基本上所有跟背包问题相关的问题的方程都是由它衍生出来的。所以有必要将它详细解释一下:将前i件物品放入容量为v的背包中这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只涉及前i-1件物品的问题。
如果不放第i件物品,那么问题就转化为前i-1件物品放入容量为v的背包中,此时能获得的价值为f[i-1][v];
如果放第i件物品,那么问题就转化为前i-1件物品放入剩下的容量为v-c[i]的背包中,此时能获得的最大价值就是:f[i-1][v-c[i]]+w[i]。
代码:
#include<iostream> #include<cstring> using namespace std; int v[1003],w[1003],dp[1003]; int main() { int t,i,j,n,m; cin>>t; while(t--) { cin>>n>>m; for(i=1;i<=n;i++) cin>>v[i];//价值 for(i=1;i<=n;i++) cin>>w[i];//体积 memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) for(j=m;j>=w[i];j--) dp[j]=max(dp[j],dp[j-w[i]]+v[i]); cout<<dp[m]<<endl; } }
相关文章推荐
- [leetcode] 342. Power of Four 解题报告
- java linux book
- hihoCoder 1044 状态压缩·一
- NTP 服务进程修复了一大波安全漏洞,请尽快升级
- linux中的Curl工具
- Swift--枚举类型
- iOS通讯录
- 200+值得收藏的设计师资源站
- Scala学习笔记-声明值和变量
- Best Coder 1003 string(dp)
- 【Android】实验8 SQLite数据库操作2016.5.12
- 父母老了
- maven添加jar到本地仓库
- 【Android】实验7 BindService模拟通信 截止提交日期2016.5.3
- oracle数据库的安装、配置与无残留卸载
- LeetCode 332. Reconstruct Itinerary(重构行程)
- java perf
- RecyclerView的 setEmptyView
- Win10一周年更新14332版SDK:10240和10586正式版无法运行
- display:block