背包问题
在n个物品中挑选若干物品装入背包,最多能装多满?假设背包的大小为m,
每个物品的大小为A[i].
样例 1:
输入:
[3,4,8,5], backpack size=10
输出:
9
样例 2:
输入:
[2,3,5,7], backpack size=12
输出:
12
解答:
定义:DP[i][j]表示有i个物品并且容量为j时,能装下的最大值。
根据第i个物品仅有2种方案:
1. 装入:此时为DP[i-1][j-A[i]] + A[i]
2. 不装入:此时为DP[i-1][j]
3. DP[i][j]将取2者其大
则有状态转换方程:
DP[i][j] = max{DP[i-1][j-A[i]] + A[i], DP[i-1][j]}
class Solution {
public:
/**
* @param m: An integer m denotes the size of a backpack
* @param A: Given n items with size A[i]
* @return: The maximum size
*/
int backPack(int m, vector<int> &A) {
// write your code here
if(A.empty() || m == 0){
return 0;
}
int n = A.size() + 1;
int **dp = new int*[n];
for (int i = 0; i < n; i++) {
dp[i] = new int[m + 1];
for (int j = 0; j < m + 1; j++) {
dp[i][j] = 0;
}
}
for (int i = 1; i < n; i++) {
dp[i][1] = 0;
}
for (int i = 1; i < m + 1; i++) {
if(A[0] <= i)
dp[1][i] = A[0];
}
// 从第一件物品到n件物品
for (int i = 1; i < n; i++) {
// 从容量1 到容量m
for (int j = 1; j <= m; j++) {
// 放得下
if(A[i-1] <= j){
dp[i][j] = max(dp[i-1][j], dp[i-1][j-A[i-1]] + A[i-1]);
}
// 放不下
else{
dp[i][j] = dp[i-1][j];
}
}
}
int MAX = dp[n - 1][m];
for (int i = 0; i < n; i++) {
delete[] dp[i];
}
delete[] dp;
return MAX;
}
};