1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
| '''problem1 0-1背包 输出受限背包容量的最优价值 '''
def knapsack(w, n, wt, val): dp = [[0] * (w + 1) for _ in range(n+1)] for i in range(1, n+1): for j in range(1, w+1): if j - wt[i-1] < 0: dp[i][j] = dp[i-1][j] else: dp[i][j] = max(dp[i-1][j-wt[i-1]] + val[i-1], dp[i-1][j]) return dp[n][w]
def knapsack(w, n, wt, val): dp = [0] * (w+1) for i in range(n): for j in range(w, 0, -1): if wt[i] <= j: dp[j] = max(dp[j], dp[j - wt[i]] + val[i]) return dp[-1] n = 3 w = 4 wt = [2, 1, 3] val = [4, 2, 3] print(knapsack(w, n, wt, val))
'''problem2 0-1背包变体 leetcode416 输出能否凑出具体背包容量 '''
class Solution: def canPartition(self, nums: List[int]) -> bool: nums_sum = sum(nums) if nums_sum % 2 != 0: return False nums_sum //= 2 nums_len = len(nums) dp = [[False] * (nums_sum + 1) for _ in range(nums_len + 1)] for i in range(nums_len + 1): dp[i][0] = True for i in range(nums_len + 1): for j in range(nums_sum + 1): if j - nums[i-1] < 0: dp[i][j] = dp[i-1][j] else: dp[i][j] = dp[i-1][j] or dp[i-1][j-nums[i-1]] return dp[nums_len][nums_sum]
class Solution: def canPartition(self, nums: List[int]) -> bool: nums_len = len(nums) nums_sum = sum(nums) if nums_sum % 2 != 0: return False nums_sum //= 2 dp = [False] * (nums_sum + 1) dp[0] = True for i in range(nums_len): for j in range(nums_sum, -1, -1): if j - nums[i] >= 0: dp[j] = dp[j] or dp[j - nums[i]] return dp[nums_sum]
''' problem3 完全背包 输出可能的组合总数 '''
def combinationSum(candidates, target): n = len(candidates) dp = [[0] * (target + 1) for _ in range(n + 1)] for i in range(n + 1): dp[i][0] = 1 for i in range(1, n + 1): for j in range(1, target + 1): if j - candidates[i - 1] < 0: dp[i][j] = dp[i - 1][j] else: dp[i][j] = dp[i - 1][j] + dp[i][j - candidates[i - 1]] print(dp) return dp[-1][-1]
def combinationSum(candidates, target): n = len(candidates) dp = [0] * (target + 1) dp[0] = 1 for i in range(n): for j in range(1, target + 1): if j - candidates[i] >= 0: dp[j] += dp[j - candidates[i]] return dp[-1] candidates = [2,3,6,7] target = 7 print(combinationSum(candidates, target))
'''problem4 完全背包变体 leetcode39 输出具体组合情况 '''
class Solution: def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: dp = {i:[] for i in range(target+1)} dp[0] = [[]] for num in candidates: for i in range(num, target+1): if dp[i-num]: for a in dp[i-num]: dp[i].append([num]+a) return dp[target]
|