Description:
有num个重量和价值分别为 weight[i] 和 value[i] 的物品。从这些物品中挑选出总重量不超过capacity的物品(背包容量)。
请问:所有挑选方案中价值总和的最大值。
Input:
物品个数,每个物品的价值和重量,背包容量。
Output:
最大价值。
Sample Input:
4
2 3
1 2
3 4
2 2
Sample Output:
7
思路一:递归
遍历每一种可能的情况,从第一件物品开始判断装或者不装,返回装第一件物品和不装第一件物品当中的较大值。当递归到物品下标为num的时候直接返回零,因为这个时候我们已经完成了判断。
Code:
#include<iostream>
using namespace std;
int weight[100001];
int value[100001];
int num;
int capacity;
int Dp(int i, int j) {
if (i == num)
return 0;
else {
if (weight[i] > j)
return Dp(i + 1, j);
else
return max(Dp(i + 1, j), Dp(i + 1, j - weight[i]) + value[i]);
}
}
void solution() {
cout << Dp(0, capacity);
}
int main() {
cin >> num;
for (int i = 0;i < num;i++) {
cin >> weight[i] >> value[i];
}
cin >> capacity;
solution();
return 0;
}
思路二:剪枝递归(DP数组)
在我们使用第一中方法递归时,我们会经常遇到重复递归的情况。但是如果我们每一次运算之后都将这一种状态记录下来,在下一次遇到这种情况时我们就可以直接使用,而不用重复递归。这样大大节约了时间成本。
Code:
#include<iostream>
#include<string.h>
using namespace std;
int weight[10001];
int value[10001];
int num;
int capacity;
int dp[10001][10001];
int D_program(int i, int j) {
int temp;
if (dp[i][j] >= 0)
return dp[i][j];
if (i == num - 1) {
if (weight[i] > j)
temp = 0;
else
temp = value[i];
dp[i][j] = temp;
return dp[i][j];
}
if (weight[i] > j)
temp = D_program(i + 1, j);
else
temp = max(D_program(i + 1, j), D_program(i + 1, j - weight[i]) + value[i]);
dp[i][j] = temp;
return dp[i][j];
}
void solution() {
memset(dp, -1, sizeof(dp));
cout << D_program(0, capacity);
}
int main() {
cin >> num;
for (int i = 0;i < num;i++) {
cin >> weight[i] >> value[i];
}
cin >> capacity;
solution();
return 0;
}
思路三:循环
如果我们充分利用构造的dp数组的话,我们姐可以不需要递归。我们只需要利用数组中的已知值,充分填充数组中的每一种可能值,就能计算出数组中所有情况的可能值,这样我们直接使用数组中的值就可以了,不需要递归。
Code:
#include<iostream>
#include<string.h>
using namespace std;
int weight[10001];
int value[10001];
int dp[10001][10001];
int num;
int capacity;
void solution() {
memset(dp, 0, sizeof(dp));
for (int i = num - 1;i >= 0;i--)
for (int j = 0;j <= capacity;j++) {
if (weight[i] > j)
dp[i][j] = dp[i + 1][j];
else
dp[i][j] = max(dp[i + 1][j], dp[i + 1][j - weight[i]] + value[i]);
}
cout << dp[0][capacity];
}
int main() {
cin >> num;
for (int i = 0;i < num;i++) {
cin >> weight[i] >> value[i];
}
cin >> capacity;
solution();
return 0;
}