完全背包
每个重量的物品数量不限,装背包的问题;纯完全背包先遍历背包和物品都可以,但是题目如果稍微变一下就会变了。而01背包先遍历任何一个都可以,但是一般写法写的都是外层物品,内层背包。
- 如果求组合数就是外层for循环遍历物品,内层for遍历背包。
- 如果求排列数就是外层for遍历背包,内层for循环遍历物品。
- 注意区别:01背包的背包遍历是倒序,完全背包的遍历是正序(因为无数个物品,正向遍历可以使后序加上)
518.零钱兑换II
- 求装满背包有几种方法,公式都是:dp[j] += dp[j - nums[i]]
class Solution:
def change(self, amount: int, coins: List[int]) -> int:
dp = [1] + [0]*amount
for i in coins:
for j in range(i,amount+1):
dp[j] += dp[j-i]
return dp[-1]
377. 组合总和 Ⅳ
class Solution:
def combinationSum4(self, nums: List[int], target: int) -> int:
dp = [1] + [0]*target
for j in range(target+1):
for i in nums:
if j>=i:
dp[j] += dp[j-i]
return dp[-1]
322. 零钱兑换
- 完全背包 组合数,注意初始化和返回值
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
dp = [0] + [float('inf')]*amount
for i in coins:
for j in range(i,amount+1):
## 有些会溢出的编程语言 加一句判断才行
#if dp[j-i]!=float('inf'):
dp[j] = min(dp[j],dp[j-i]+1)
return -1 if dp[-1]==float('inf') else dp[-1]
279.完全平方数
- 数字 i^2 为物品重量,n为背包容量
class Solution:
def numSquares(self, n: int) -> int:
w = int(n**0.5)
if w*w==n:
return 1
dp = [0] + [float('inf')]*n
for i in range(w+1):
iw = i*i
for j in range(iw,n+1):
if dp[j-iw]!=float('inf'):
dp[j] = min(dp[j],dp[j-iw]+1)
return dp[-1]
139.单词拆分
- 单词是物品,字符串是背包,想好思路慢慢写
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
dp = [True] + [False]*len(s)
for j in range(1,len(s)+1):
for i in wordDict:
if j>=len(i) and i == s[j-len(i):j]:
dp[j] = dp[j] or dp[j-len(i)]
return dp[-1]