题目描述:
按图中样例分析
已知输入:
物品编号 | 1 | 2 | 3 | 4 |
重量weight | 1 | 2 | 3 | 4 |
价值value | 2 | 4 | 4 | 5 |
物品个数为:4、背包总容量为:5。建立数组v[i]储存价值,w[i]储存重量。
建立二维数组dp[i][j],横轴为j,代表背包容量大小,纵轴为i代表第i个物品。
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 0 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
2 | 0 | 2 | 4 | 6 | 6 | 6 | 6 | 6 | 6 |
3 | 0 | 2 | 4 | 6 | 6 | 8 | 10 | 10 | 10 |
4 | 0 | 2 | 4 | 6 | 6 | 8 | 10 | 11 | 11 |
解决此问题的关键是找出递推式
表中二维数组dp[i][j]的值代表的是放入容量为j的前i件物品的最大价值。如当i=1,j>1时,第一件物品的体积为1价值为2,此时的背包均可放下,所以价值都为2.
物体的状态共有两种:放与不放。
不放:
当j<w[i]时,说明就算此刻背包是空的,也放不进第i件物品,所有此刻背包的最大价值就是之前的最大价值:dp[i-1][j]。因为它根本就放不进去第i见物品,所以不用考虑。
放:
当j>=w[i]时,此时可以放进背包。但要判断放了价值更高还是不放价值高。判断的方法就是先找到dp[i-1][j-w[i]],i-1说明是还没放,j-w[i]就是背包容量减去此物品还剩下的容量。也就是找到没放这个物品之前它的最大价值。然后dp[i-1][j-w[i]]+v[i]就是放了这个物品的最大价值,让它再与dp[i-1][j]比较大小,取大者赋给此时的dp[i][j]。
具体代码如下:
#include <bits/stdc++.h>
using namespace std;
int bag(int n,int m);
int num[1001][1001]={0};
int v[1001];
int w[1001];
int main()
{
int N,V,i;
cin>>N>>V;
for(i=1;i<=N;i++){
cin>>w[i]>>v[i];
}
cout<<bag(N,V);
}
int bag(int n,int m)
{
int i,j;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
if(j<w[i]){
num[i][j]=num[i-1][j];
}
else{
num[i][j]=max(num[i-1][j],num[i-1][j-w[i]]+v[i]);
}
}
}
return num[n][m];
}