解析
首先设置一个二维数组dp[i][j],令其表示前i个物品装进容量为j的背包能获得的最大价值.
dp[n][m]的值就是0-1背包问题的解.只考虑第i件物品时,将情况分为是否放入第i件物品两种:
- 对于容量为j的背包,
如果已经无法放入第i件物品,那么这个问题就转化成将前i-1个物品放入容量为j的背包的问题即dp[i][j]=dp[i-1][j] - 对于容量为j的背包,
如果还能放入第i件物品,那么放它之后背包容积缩减为j-v[i],且已知这个物品的价值w[i],这个问题就转化成了将前i-1个物品放入容量为j-v[i]的背包的问题即dp[i][j]=dp[i - 1][j - v[i]] + w[i]从这两种情况可以得到状态转移方程dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i])
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1005;
int v[N]; // 体积
int w[N]; // 价值
int dp[N][N]; // dp[i][j],前i件物品,背包容量为j的情况下的能装物品的最大价值
int main()
{
int n, m;
scanf("%d%d",&n,&m); // n物品数量 m背包容积
for(int i = 1; i <= n; i++)
scanf("%d%d",&v[i],&w[i]);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
{
// 剩余容量装不进第i个物品,则价值无法更新
if(j < v[i])
dp[i][j] = dp[i - 1][j];
// 能装进去,则比较装/不装第i件物品,哪个价值更高
else
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i]);
}
printf("%d\n",dp[n][m]);
return 0;
}