题目:
有n个重量和价值分别为wi,vi的物品。从这些物品中挑选出总重量不超过W的物品,求所有挑选方案中价值总和的最大值。
1<=n<=100
1<=wi<=10^7
1<=n<=100
1<=wi<=10^7
1<=vi<=100
1<=W<=10^9
1<=W<=10^9
分析:
将背包的重量 j 从0开始到最大容量W,逐步看所能装物品的最大价值
如果背包的重量小于第i个物品的重量(即j < w[i],放不下该物品),,则背包中只装有之前这个容量里面装的物品,即dp[i][j] = dp[i+1][j];否则的话,装入价值最大的物品,将原先容量装的物品的价值(dp[i+1][j])与重新装入之后的价值(dp[i+1][j-w[i]]+v[i])相比较大的那部分.最后将二维数组最右上角的值输出即可。
书中的图表:
另外一种:
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int n;
int w[100],v[100];
int dp[100][100]; //存放背包不同的容量的价值,一定不要忘记初始化
int W;
int V; //最后的总价值
void solve()
{
for(int i=n;i>=1;i--)
{
for(int j=0;j<=W;j++)
{
//dp[i][j] 为从第i个物品开始挑选总重量小于j时,总价值的最大值
if(j < w[i])
dp[i][j] = dp[i+1][j];
else
dp[i][j] = max(dp[i+1][j],dp[i+1][j-w[i]]+v[i]);
}
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&w[i],&v[i]);
scanf("%d",&W);
solve();
printf("%d\n",dp[1][W]);
return 0;
}