LeetCode1262.可被三整除的最大和

打嗝_小王子發表於2020-10-02

先貼上我寫的笨笨的程式碼,但是超時了。。。我用DP把nums列表中所有元素可能出現的組合都列舉出來,判斷是否被三整除;

class Solution(object):
    def maxSumDivThree(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        ss = sum(nums)
        maxSumDivThree = 0
        # dp[i][j]陣列表示:前i個元素可以組合成j為True,否則為False
        dp = [False] * (ss+1)
        dp[0] = True
        for i in range(len(nums)):
            for j in range(ss, nums[i]-1, -1):
                dp[j] = dp[j-nums[i]] or dp[j]
                if dp[j] and j%3==0 and j>maxSumDivThree:
                    maxSumDivThree = j
        return maxSumDivThree

該演算法的複雜度為O(N*sum),結果肯定就是:

於是,我學習了力扣大神的思路:動態規劃與狀態轉移

定義

dp[i][0]表示nums[0...i]模三餘零的最大和——零狀態:當前數字最大和模三餘零

dp[i][1]表示nums[0...i]模三餘一的最大和——一狀態:當前數字最大和模三餘一

dp[i][2]表示nums[0...i]模三餘二的最大和——二狀態:當前數字最大和模三餘二

 image.png

image.png 

image.png 

 

def DPandState(self, nums):
    dp = [[0] * 3 for _ in range(len(nums)+1)]
    dp[0][1] = -1
    dp[0][2] = -1
    for i in range(1, len(nums)+1):
        if nums[i-1]%3 == 0:
            dp[i][0] = max(dp[i-1][0], dp[i-1][0]+nums[i-1])
            dp[i][1] = max(dp[i-1][1], dp[i-1][1]+nums[i-1])
            dp[i][2] = max(dp[i-1][2], dp[i-1][2]+nums[i-1])
        elif nums[i-1]%3 == 1:
            dp[i][0] = max(dp[i-1][0], dp[i-1][2]+nums[i-1])
            dp[i][1] = max(dp[i-1][1], dp[i-1][0]+nums[i-1])
            dp[i][2] = max(dp[i-1][2], dp[i-1][1]+nums[i-1])
        elif nums[i-1]%3 == 2:
            dp[i][0] = max(dp[i-1][0], dp[i-1][1]+nums[i-1])
            dp[i][1] = max(dp[i-1][1], dp[i-1][2]+nums[i-1])
            dp[i][2] = max(dp[i-1][2], dp[i-1][0]+nums[i-1])
    return dp[len(nums)][0]

 

相關文章