01背包问题——<DP>
来源:互联网 发布:wp8软件下载 编辑:程序博客网 时间:2024/06/10 20:52
对于这方方程其实并不难理解,方程之中,现在需要放置的是第i件物品,这件物品的体积是c[i],价值是w[i],因此f[i-1][v]代表的就是不将这件物品放入背包,而f[i-1][v-c[i]]+w[i]则是代表将第i件放入背包之后的总价值,比较两者的价值,得出最大的价值存入现在的背包之中。
题目描述:
假设山洞里共有a,b,c,d ,e这5件宝物(不是5种宝物),它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包, 怎么装背包,可以才能带走最多的财富。
有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?
此例题参考博客:动态规划之01背包问题(最易理解的讲解)先对表进行大概的说明,前面三列是物品名字,重量和价值。后面1到10表示背包容量。
e3表示背包容量为3,当前物品为e。 装不下
d3表示背包容量为3,当前物品为e,d。装不下
c3表示背包容量为3,当前物品为e,d,c。 装不下
b3表示背包容量为3,当前物品为e,d,c,b 可以装b物品,所以值为b物品的价值3
a3表示背包容量为3,当前物品为e,d,c,b ,a 这时根据状态转移方程,比较b3和b1+a的价值的值。
后者更大,所以a3值为6.
当时看了上面博客的讲解后自己画出了上面这张表,可是比较好奇为什么要从最后一件物品开始往里面装,不能从第一件物品直接开始装嘛?
于是再次从第一件物品以同样的填法进行填表,发现其实结果是一样的,并没有影响。
这里对e8进行说明,d8为11,当前容量8减去e的重量4=4,所以寻找d4值 为9 9+6=15>11 所以e8的值更新为15
一道例题:有一个容量为m(1<=m<=4000000)的背包,有n(1<=n<=16)个物品,每个物品有体积v(1<=v<=2012)和价值w(0<=2012),现在要你选择一些物品,使得背包所装物品的总价值最大。
C++代码:
#include <iostream>#include <memory.h>using namespace std;struct wupin{ int v;//体积 int w;//价值}a[10000];int dp[10000][10000];int main(){ int n,m; cin>>m>>n; memset(dp,0,sizeof(dp)); memset(a,0,sizeof(a)); for(int i=1;i<=n;i++) cin>>a[i].v>>a[i].w; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(j>=a[i].v) dp[i][j]=max(dp[i-1][j],dp[i-1][j-a[i].v]+a[i].w); else dp[i][j]=dp[i-1][j]; }// for(int i=1;i<=n;i++)// {// for(int j=1;j<=m;j++)// cout<<dp[i][j]<<' ';// cout<<endl;// } cout << dp[n][m] << endl; return 0;}一般写法:
大小为j的背包是否放第i个物品,取决于大小为(j-a[i].v)的背包的最优解+a[i].w 是否大于当前不放这个物品的最优解的价值
#include <iostream>#include <memory.h>using namespace std;struct wupin{ int v;//体积 int w;//价值}a[10000];int dp[100000];int main(){ int n,m; cin>>m>>n; memset(dp,0,sizeof(dp)); memset(a,0,sizeof(a)); for(int i=0;i<n;i++) cin>>a[i].v>>a[i].w; for(int i=0;i<n;i++) for(int j=m;j>=a[i].v;j--) dp[j]=max(dp[j],dp[j-a[i].v]+a[i].w); cout << dp[m] << endl; return 0;}
最简洁的写法:
#include <cstdio>#include <algorithm>using namespace std;int f[1005];int n,m;int main(){ int w,v; scanf("%d%d",&m,&n); for(int i=1;i<=n;i++) { scanf("%d%d",&v,&w); for(int j=m;j>=v;j--) f[j]=max(f[j],f[j-v]+w); } printf("%d\n",f[m]); return 0;}
- DP —> 背包问题
- 01背包问题——<DP>
- DP 背包问题 01背包
- 算法复习——背包DP问题
- 0—1背包问题(dp)
- HDU1203 DP 01背包问题
- 01背包问题 第一次DP
- dp-01背包问题代码
- dp—完全背包
- 背包问题——01背包、完全背包、多重背包、混合三种背包问题
- 背包问题(1)——01背包、完全背包、多重背包、混合三种背包问题
- 01背包问题——经典DP问题,优化与未优化
- 背包问题——01背包
- HDU—2955 DP—01背包
- HDU—1203 DP—01背包
- HDU—1171 DP 01背包
- 【NOIP模板①】经典DP——背包问题
- [DP]51 Nod 1597——有限背包计数问题
- Qt编写导航按钮
- java 开发模式之十二 : 状态模式
- Spring Boot 公共配置
- 绝对路径和相对路径
- iOS传感器:使用陀螺仪完成一个小球撞壁的小游戏
- 01背包问题——<DP>
- 从零开始构建计算机系统——二维图形库(直线)
- EF查询创建上下文实体对象
- 手机软件APP积累
- python3入门与进阶(一)
- 专家预言 2040 年,机器将代替人类编写代码!程序员要下架啦?
- 博客报到
- 397. Longest Increasing Continuous Subsequence
- 剑指Offer---表示数值的字符串