你有一个背包,最多能容纳的体积是V。
现在有n种物品,每种物品有任意多个,第i种物品的体积为
,价值为
。
(1)求这个背包至多能装多大价值的物品?
(2)若背包恰好装满,求至多能装多大价值的物品?
数据范围: 
6,2,[[5,10],[3,1]]
[10,2]
8,3,[[3,10],[9,1],[10,1]]
[20,0]
无法恰好装满背包。
13,6,[[13,189],[17,360],[19,870],[14,184],[6,298],[16,242]]
[596,189]
可以装5号物品2个,达到最大价值298*2=596,若要求恰好装满,只能装1个1号物品,价值为189.
class Solution: def knapsack(self , v: int, n: int, nums: List[List[int]]) -> List[int]: dp = [0]*(v+1) for i in range(n): for j in range(0, v - nums[i][0]+1): # 完全背包问题,正向遍历容量 if dp[j] != 0&nbs***bsp;j == 0: dp[j+ nums[i][0]] = max(dp[j+ nums[i][0]], dp[j] + nums[i][1]) return [max(dp), dp[v]]
cpp,完全背包模板
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param v int整型 * @param n int整型 * @param nums int整型vector<vector<>> * @return int整型vector */ vector<int> knapsack(int v, int n, vector<vector<int> >& nums) { // write code here vector<int> dp1(v + 1, 0), dp2(v + 1, -1); dp2[0] = 0; for (int i = 0; i < n; ++i) { for (int j = nums[i][0]; j <= v; ++j) { dp1[j] = max(dp1[j], dp1[j - nums[i][0]] + nums[i][1]); if (dp2[j - nums[i][0]] >= 0) { dp2[j] = max(dp2[j], dp2[j - nums[i][0]] + nums[i][1]); } } } int res1 = dp1[v]; int res2 = dp2[v] >= 0 ? dp2[v] : 0; return {res1, res2}; } };
func knapsack( v int , n int , nums [][]int ) []int { dp,dp1 := make([]int, v + 1), make([]int, v + 1) for tmpV := 1; tmpV <= v; tmpV++ { // 遍历容量v作为状态复用 max, max1 := 0, 0 for i := 1; i <= len(nums);i++ { iv := nums[i - 1][0] iw := nums[i - 1][1] if tmpV >= iv { // 1. 放入第i种物品刚好得到最大价值 if max < dp[tmpV - iv] +iw { max = dp[tmpV - iv] +iw } //2 第j种物品刚好填满i个容量 得到最大价值 if (tmpV - iv == 0 || dp1[tmpV - iv] != 0) && max1 < dp1[tmpV - iv] + iw { max1 = dp1[tmpV - iv] + iw } } } dp[tmpV], dp1[tmpV] = max, max1 } return []int{dp[v], dp1[v]} }