问题描述
设有背包问题物品n个,背包总容量为sum,每个物品重量为wi,物品装入背包的收益为pi。输入n,sum,每个物品重量和收益,求出最大收益。
输入
7 15
2 3 5 7 1 4 1
10 5 15 7 6 18 13
输出
62
解题思路:我们需要收益最大,所以收益高的物品要优先装入背包吗?显然不是的,背包的容量是固定的,我们不能无限次的装。当我们把较小体积和较大收益的物品装入背包时,可得到最大收益,问题是我们要怎么装呢。
1,设i表示第i个物品,j表示当前背包的容量。
2,f[i][j]表示第i个物品装入容量为j的背包中所能获得的最大收益。
3,f[n][sum]即为所求答案,即第n个物品装入容量为sum的背包中所能获得的最大收益。
代码
#include<iostream>
using namespace std;
const int N = 100;
int w[N], p[N], f[N][N];//前i个物品装入容量为j的背包中获得的收益
int n;
int sum;
int main()
{
cin >> n >> sum;
for(int i = 1; i <= n; i++)
cin >> w[i];
for(int i = 1; i <= n; i++)
cin >> p[i];
for(int i = 1; i <= n; i++){
for(int j = 1; j <= sum; j++){
f[i][j] = f[i - 1][j]; //未选第i件物品
if(j > w[i]) //表明背包剩余空间可以放下第i件物品
f[i][j] = max(f[i][j], f[i - 1][j - w[i]] + p[i]);
//比较方第i件物品和不放那种收益较大
}
}
cout << f[n][sum];
return 0;
}
优化版
#include<bits/stdc++.h>
//优化版,一维数组
using namespace std;
const int N = 1100;
int w[N], p[N], f[N];
int n, sum;
int main(){
cin >> n >> sum;
for(int i = 1; i <= n; i++){
cin >> w[i];
}
for(int i = 1; i <= n; i++){
cin >> p[i];
}
for(int i = 1; i <= n; i++){
for(int j = sum; j >= w[i]; j--){
f[j] = max(f[j], f[j - w[i]] + p[i]);
}
}
cout << f[sum];
}