简单背包问题
有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。第 i 件物品的体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。输出最大价值。
输入格式:
第一行两个整数,N,V ,用空格隔开,分别表示物品数量和背包容积。接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。
输出格式:
输出一个整数,表示最大价值。数据范围0<N,V≤1000 ,0<vi,wi≤1000
输入样例:
4 5
1 2
2 4
3 4
4 5
输出样例:在这里插入代码片
8
样例解释
物品号\容量 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
物品1 | 2 | 2 | 2 | 2 | 2 |
物品2 | 2 | 4 | 6 | 6 | 6 |
物品3 | 2 | 4 | 6 | 6 | 8 |
物品4 | 2 | 4 | 6 | 6 | 8 |
1.当我们放入第一个物品时,我们看一看在背包不同的容量下最大价值是多少,我们发现第一行的结果。
2.当又有一件物品可以放置时,我们再次进行检查,我们发现当容量为1时,物品2放不进去,那我们看看在此之前容量为1时最大的价值是多少,我们发现在此之前物品1放入容量1时价值最大。当容量为2时,物品2可以放下,此时我们可以得知最大价值是4。当容量为3时,我们发现背包可以装下,此时我们还有1个容量,排除装进去的物品2,在此之前容量为1最大价值为2.
…
对此的规律:
1.放不下,最大价值为同等的容量前i-1件物品的价值。
2.放得下,max(同等的容量前i-1件物品的价值。, 当前物品价值与前i-1件物品下容量为剩余容量的最大价值)
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1008;
int v[N]; // 第i件物品的容量
int w[N]; // 第i件物品的价值
int dp[N][N]; // 在第i件物品时,j容量是最大价值是多少
int n,m;
int main()
{
//std::ios::sync_with_stdio(false);
cin>>n>>m;
for(int i = 1;i <= n;i++){
cin>>v[i]>>w[i];
}
for(int i = 1;i <= n;i++ ){
for(int j = 1; j <= m;j++){
if(j < v[i])dp[i][j] = dp[i-1][j]; // 当放不下时,最大价值为第i-1件物品时的最大价值。
else{
dp[i][j] = max(dp[i-1][j],dp[i-1][j-v[i]] + w[i]); // 放得下时,比较。
}
}
}
cout<<dp[n][m]<<endl;
}