2021-08-05:动态规划2

class Solution:
    def findLongestChain(self, pairs: List[List[int]]) -> int:
        n = len(pairs)
        pairs.sort()
        dp = [1]*n
        for i in range(n):
            for j in range(i):
                if pairs[i][0] > pairs[j][1]:
                    dp[i] = max(dp[i],dp[j]+1)
        return max(dp)

class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:
        n = len(nums)
        dp = [[1]*2 for _ in range(n)]  #[i][0] 这数应该比之前的数大,[i][1] 这数应该比之前的数小
        ans = 1
        for i in range(n):
            for j in range(i):
                if nums[j] < nums[i]:
                    dp[i][0] = max(dp[i][0],dp[j][1]+1)
                if nums[j] > nums[i]:
                    dp[i][1] = max(dp[i][1],dp[j][0]+1)
            ans = max(dp[i][0] ,dp[i][1])
        return ans
                    
                
        

错误代码:

class Solution:
    def longestCommonSubsequence(self, text1: str, text2: str) -> int:
        m = len(text1)
        n = len(text2)
        dp = [[0]*n for _ in range(m)]
        for i in range(m):
            for j in range(n):
                if text1[i] == text2[j]:
                    print(text1[i])
                    dp[i][j] = dp[i-1][j-1] + 1 
                    print(i-1,j-1)
                    
                else:
                    dp[i][j] = max(dp[i-1][j],dp[i][j-1])
        return dp[m-1][n-1]
                    
        

错误原因:

第一个字母相同的时候,变成dp[0][0] = dp[-1][-1] +1

正确代码:

class Solution:
    def longestCommonSubsequence(self, text1: str, text2: str) -> int:
        m = len(text1)
        n = len(text2)
        dp = [[0]*(n+1) for _ in range(m+1)]
        for i in range(1,m+1):
            for j in range(1,n+1):
                if text1[i-1] == text2[j-1]:
                    dp[i][j] = dp[i-1][j-1] + 1 
                else:
                    dp[i][j] = max(dp[i-1][j],dp[i][j-1])
        return dp[m][n]
                    
        

超时答案:

class Solution:
    def findTargetSumWays(self, nums: List[int], target: int) -> int:
        self.ans = 0
        self.N = len(nums)
        self.nums = nums
        self.findTargethelper(target,0,[0])
        return self.ans
    def findTargethelper(self,target,n,res):
        cur = []
        for result in res:
            result1 = result + self.nums[n]
            result2 = result - self.nums[n]
            cur.append(result1)
            cur.append(result2)
        res = cur
        if n == self.N - 1:
            for current in cur:
                if current == target:
                    self.ans += 1
            return
        self.findTargethelper(target,n+1,res)
        
        
            
        

正确答案:

用dp来做:

假设加的数字和为x,减的数字和为y,那么x + y = target, x - y = sum

x = (target+sum)/2,  那么题目就变成了0 1 背包问题。选取数字使得他们的和为 (target + sum) / 2

但前提条件是, target < sum,并且x是一个整数 

class Solution:
    def findTargetSumWays(self, nums: List[int], target: int) -> int:
        if sum(nums) < target or (sum(nums)+target) % 2 != 0:
            return 0
        ans = (target + sum(nums))//2

        dp = [1]+[0]*(ans)
        for num in nums:
            for i in range(ans,num-1,-1):
                dp[i] += dp[i-num]
        return dp[-1]

 

class Solution:
    def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
        dp = [[0]*(n+1) for _ in range(m+1)]
        for s in strs:
            count0 = s.count('0')
            count1 = s.count('1')
            for i in range(m,count0-1,-1): 
                #倒序保证每个元素只遍历一次
                #count0-1,遍历这个元素的时候,确定选它的情况一定是i-count0
                for j in range(n,count1-1,-1):
                    dp[i][j] = max(dp[i][j],dp[i-count0][j-count1]+1)
        return dp[-1][-1]
        

正序遍历:

 

class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        dp = [0]+[10001]*(amount)
        for coin in coins:
            for i in range(coin,amount+1):
                dp[i] = min(dp[i],dp[i-coin]+1)
        return dp[-1] if dp[-1] != 10001 else -1
        

 

class Solution:
    def change(self, amount: int, coins: List[int]) -> int:
        dp = [1]+[0]*amount
        for coin in coins:
            for i in range(coin,amount+1):
                dp[i] += dp[i-coin]
        return dp[-1]
        

按顺序完全背包问题:

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        n = len(s)
        dp = [False]*(n+1)
        dp[0] = True
        for i in range(1,n+1):
            for word in wordDict:
                l = len(word)
                if(l<=i and word == s[i-l:i]):
                    dp[i] = dp[i] or dp[i-l]
        return dp[n]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值