322. Coin Change
dp[j]:凑足总额为j所需钱币的最少个数为dp[j]
凑足总额为j - coins[i]的最少个数为dp[j - coins[i]],那么只需要加上一个钱币coins[i]即dp[j - coins[i]] + 1就是dp[j](考虑coins[i])
所以dp[j] 要取所有 dp[j - coins[i]] + 1 中最小的。
递推公式:dp[j] = min(dp[j - coins[i]] + 1, dp[j]);
本题求钱币最小个数,那么钱币有顺序和没有顺序都可以,都不影响钱币的最小个数。
所以本题并不强调集合是组合还是排列。
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
dp = [float('inf')] * (amount + 1)
dp[0] = 0
for i in range(len(coins)): # 遍历物品
for j in range(coins[i], amount + 1): # 遍历背包
dp[j] = min(dp[j], dp[j - coins[i]] + 1)
if dp[amount] == float('inf'):
return -1
return dp[amount]
279. Perfect Squares
dp[j]:和为j的完全平方数的最少数量为dp[j]
和上题一样,本题并不强调集合是组合还是排列,随便先遍历物品还是先遍历背包。
class Solution:
def numSquares(self, n: int) -> int:
dp = [float('inf')] * (n + 1)
dp[0] = 0
nums = [i*i for i in range(1, n + 1) if i*i <= n]
for num in nums: # 遍历物品
for j in range(num, n + 1): # 遍历背包
dp[j] = min(dp[j], dp[j - num] + 1)
return dp[n]