给出n个物品的体积A[i]和其价值V[i],将他们装入一个大小为m的背包,最多能装入的总价值有多大?
注意事项
A[i], V[i], n, m均为整数。你不能将物品进行切分。你所挑选的物品总体积需要小于等于给定的m。
样例
对于物品体积[2, 3, 5, 7]和对应的价值[1, 5, 2, 4], 假设背包大小为10的话,最大能够装入的价值为9。
挑战
O(n x m) memory is acceptable, can you do it in O(m) memory?
01背包问题的原始模型,利用二维数组进行求解。
空间复杂度O(n * m)
class Solution { public: /* * @param m: An integer m denotes the size of a backpack * @param A: Given n items with size A[i] * @param V: Given n items with value V[i] * @return: The maximum value */ int backPackII(int m, vector<int> A, vector<int> V) { // write your code here if (m == 0 || A.empty() || V.empty()) return 0; vector<vector<int>> dp(A.size(), vector<int>(m + 1, 0)); for (int j = 0; j != m + 1; j++) { if (j >= A[0]) dp[0][j] = V[0]; } for (int i = 1; i != A.size(); i++) { for (int j = 1; j != m + 1; j++) { if (j >= A[i]) dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - A[i]] + V[i]); else dp[i][j] = dp[i - 1][j]; } } return dp[A.size() - 1][m]; } };
将二维数组优化为一维数组,注意内层for循环逆序。
class Solution { public: /* * @param m: An integer m denotes the size of a backpack * @param A: Given n items with size A[i] * @param V: Given n items with value V[i] * @return: The maximum value */ int backPackII(int m, vector<int> A, vector<int> V) { // write your code here if (m == 0 || A.empty() || V.empty()) return 0; vector<int> dp(m + 1, 0); for (int i = 0; i != A.size(); i++) { for (int j = m; j != 0; j--) { if (j >= A[i]) dp[j] = max(dp[j], dp[j - A[i]] + V[i]); else dp[j] = dp[j]; } } return dp[m]; } };
相关题目: