有一个背包可以装一定重量的物品,如何装物品才能使背包的价值最大:
此背包容量为10
物品编号 | 1 | 2 | 3 | 4 | 5 |
物品重量 | 5 | 3 | 4 | 4 | 2 |
物品价值 | 10 | 5 | 8 | 9 | 6 |
记f(k,w):背包容量为w,现有k件物品可以装,所能装的最大价值。
对于本题,背包最大容量为10,有5件物品,求f(5,10):
按序号选择是否放入背包:放入时加入放入物品的价值,同时背包减去放入物品的重量,如图所示,当背包不足以放入物品或无法放入物品时停止如f(0,x),x为背包重量,:
写入记录表格,记f(k,w):背包容量为w,现有k件物品可以装,所能装的最大价值。
动态规划的重要思想就是更新,存储,每当需要时调用,不需要重新执行程序:
物品序号\背包大小 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1:w=5 v=10 | 0 | 0 | 0 | 0 | 0 | 10 | 10 | 10 | 10 | 10 | 10 |
2: w=3 v=5 | 0 | 0 | 0 | 5 | 5 | 10 | 10 | 10 | 15 | 15 | 15 |
3:w=4 v=8 | 0 | 0 | 0 | 5 | 8 | 10 | 10 | 13 | 15 | 18 | 18 |
4: w=4 v=9 | 0 | 0 | 0 | 5 | 9 | 10 | 10 | 14 | 17 | 19 | 19 |
5: w=2 v=10 | 0 | 0 | 6 | 6 | 9 | 11 | 15 | 16 | 17 | 20 | 23 |
写出状态转移方程:
f(k,w) | f(k-1,w) w(k)>w (太重放不下) |
max{f(k-1,w),f(k-1,w-w(k))+v(k) w(k)<=w |
#include<bits/stdc++.h>
using namespace std;
int f[6][11]={0};
int w[6]={0,5,3,4,4,2};
int v[6]={0,10,5,8,9,6};
int main(){
int i,j;//j表示背包容量
memset(f,0,sizeof(f)) ;
for (i=1;i<6;i++)
for(j=1;j<11;j++){
if(w[i]>j)
f[i][j]=f[i-1][j];
else
f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+v[i]);
}
for(i=0;i<6;i++)
for(j=0;j<11;j++)
cout<<"f["<<i<<"]""f["<<j<<"]="<<f[i][j]<<endl;
return 0;
}
执行结果为: