Dynamic Programming,一维当前位结尾

由于DP部分内容太过繁杂,整理一下。这一部分针对一维,主要针对以下选择

  1. 选择和上一步相同,该步不选择
  2. 选择当前数,从而再去前面找合适的

# 746. Min Cost Climbing Stairs,每次走一步或者走两步

def minCostClimbingStairs(cost):
    """
    :type cost: List[int]
    :rtype: int
    """
    n=len(cost)
    steps=[None]*n# minimum to climb across i
    if n>0:
        steps[0]=min(cost[0],0)
    if n>1:
        steps[1]=min(cost[0],cost[1])
    for i in range(2,n):# 爬过i,意味着从i出发,或者从i-1出发,但选择上上步的值
        steps[i]=min(cost[i]+steps[i-1],cost[i-1]+steps[i-2])
    print(steps)
    return steps[-1]

# 198. House Robber, 给定nums,不选择相邻的情况下求最大值

  • 要么当前不要,选上一个;要么选当前+上上个的最大值
def rob(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    n=len(nums)
    if n==0:
        return 0
    if n<=2:
        return max(nums)
    nums[1]=max(nums[0],nums[1])
    for i in range(2,n):
        nums[i]=max(nums[i-1],nums[i-2]+nums[i])
    return nums[-1]

# 213. House Robber II,环形情况,如果最后一个和第一个相邻,那么相当于求两个最大值 range(1,n) & range(n-1)

def rob2(nums):
    if not nums: return 0
    if len(nums) <= 2: return max(nums)
    def rob_row(nums):
        res = [0] * len(nums)
        res[0], res[1] = nums[0], max(nums[0], nums[1])

        for i in range(2, len(nums)):
            res[i] = max(res[i-1], res[i-2] + nums[i])

        return res[-1]

    return max(rob_row(nums[1:]), rob_row(nums[:-1]))

# 740. Delete and Earn, 和上面相似,给定很多数,每选择一个数,要将其相邻的数全删除

  • sort them by num and record the frequency
  • 如果目前的数与之前不相邻,则相加
  • 如果相邻,dp[n] = max(dp[n-1],dp[n-2]+an)
import collections
def deleteAndEarn(nums):#不选值相邻的数,每个数带一个频率
    """
    :type nums: List[int]
    :rtype: int
    """
    if not nums:
        return 0
    counts = collections.Counter(nums)
    counts = sorted(counts.items(),key=lambda x:x[0])
    cur = [0 for _ in range(len(counts))]
    cur[0] = counts[0][0]*counts[0][1]

    if len(counts)>=2:
        if counts[1][0]!=counts[0][0]+1:
            cur[1] = cur[0]+counts[1][0]*counts[1][1]
        else:
            cur[1] = max(cur[0],counts[1][0]*counts[1][1])
    for i in range(2,len(counts)):
        if counts[i][0]!= counts[i-1][0]+1:
            cur[i] = cur[i-1]+counts[i][0]*counts[i][1]
        else:
            cur[i] = max(cur[i-1],cur[i-2]+counts[i][0]*counts[i][1])
    return cur[-1]

猜你喜欢

转载自www.cnblogs.com/dl3182/p/11955478.html
今日推荐