最少种类问题,采用min函数,除了【0】以外用inf初始化
任何遍历顺序都可以
若最后一位是inf,说明无方法可以组成
class Solution(object):
def coinChange(self, coins, amount):
"""
:type coins: List[int]
:type amount: int
:rtype: int
"""
dp = [0] * (amount+1)
for i in range(1,len(dp)):
dp[i] = float('inf')
for coin in coins:
for j in range(coin,amount+1):
dp[j] = min(dp[j],dp[j-coin]+1)
if dp[amount] == float('inf'):
return -1
return dp[amount]
跟上个题目一样,不过本题目使用先遍历背包再遍历物品,代码会好写一点
class Solution(object):
def numSquares(self, n):
"""
:type n: int
:rtype: int
"""
dp = [0] * (n+1)
for i in range(1,len(dp)):
dp[i] = float('inf')
for i in range(1,n+1):
for j in range(1,int(i**0.5)+1):
dp[i] = min(dp[i],dp[i-j**2]+1)
if dp[n] == float('inf'):
return -1
return dp[n]
题目三
转换为完全背包问题
确定dp数组以及下标的含义
dp[i] : 字符串长度为i的话,dp[i]为true,表示可以拆分为一个或多个在字典中出现的单词。
确定递推公式
如果确定dp[j] 是true,且 [j, i] 这个区间的子串出现在字典里,那么dp[i]一定是true。(j < i )。
所以递推公式是 if([j, i] 这个区间的子串出现在字典里 && dp[j]是true) 那么 dp[i] = true
要求排列,所以先遍历背包,再遍历物品
class Solution(object):
def wordBreak(self, s, wordDict):
"""
:type s: str
:type wordDict: List[str]
:rtype: bool
"""
wordlist = set(wordDict)
n = len(s)
dp = [0] * (n+1)
dp[0] = 1
for i in range(1,n+1):
for j in range(i):
if dp[j] == 1 and s[j:i] in wordlist:
dp[i] = 1
break
return dp[n]==1