动态规划练习

剑指 Offer II 089. 房屋偷盗

对于第ind房屋存在两种状态:偷or不偷

dp[ind] = dp[ind-2]+nums[ind]#偷:
dp[ind] = dp[ind-1]#不偷

所以优化方程为

dp[ind] = min(dp[ind-1],dp[ind-2]+nums[ind])

边界条件为:

ind=0: dp[0] = nums[0]
ind=1: dp[1] = max(nums[0],nums[1])

代码:

class Solution:
    def minCost(self, costs: List[List[int]]) -> int:
        n = len(costs)
        dp = [[0,0,0] for _ in range(n)]
        for i in range(3):
            dp[0][i] = costs[0][i]
        
        for ind in range(1,n):
            dp[ind][0] = min(dp[ind-1][1],dp[ind-1][2])+costs[ind][0]#刷R:
            dp[ind][1] = min(dp[ind-1][0],dp[ind-1][2])+costs[ind][1]#刷B:
            dp[ind][2] = min(dp[ind-1][0],dp[ind-1][1])+costs[ind][2]#刷G:
        return min(dp[n-1])

剑指 Offer II 091. 粉刷房子

对于第ind的房子存在三种状态,粉刷R,粉刷B,粉刷G:

刷R:dp[ind][0] = min(dp[ind-1][1]+dp[ind-1][2])+costs[ind][0]
刷B:dp[ind][1] = min(dp[ind-1][0]+dp[ind-1][2])+costs[ind][1]
刷G:dp[ind][2] = min(dp[ind-1][0]+dp[ind-1][1])+costs[ind][2]

初始状态:

for i in range(3):
    dp[0][i] = costs[0][i]

代码:

class Solution:
    def minCost(self, costs: List[List[int]]) -> int:
        n = len(costs)
        dp = [[0,0,0] for _ in range(n)]
        for i in range(3):
            dp[0][i] = costs[0][i]
        
        for ind in range(1,n):
            dp[ind][0] = min(dp[ind-1][1],dp[ind-1][2])+costs[ind][0]#刷R:
            dp[ind][1] = min(dp[ind-1][0],dp[ind-1][2])+costs[ind][1]#刷B:
            dp[ind][2] = min(dp[ind-1][0],dp[ind-1][1])+costs[ind][2]#刷G:
        return min(dp[n-1])

剑指 Offer II 092. 翻转字符

对于第ind个位置有两个状态,为‘0’or ‘1’

且我们知道:

ind-1为0,ind可以为0或者1

ind-1为1,ind只能为1

dp[ind][0] = dp[ind-1][0] #ind为0
dp[ind][1] = min(dp[ind-1][0],dp[ind-1][1])#ind为1

并且我们还要算上翻转次数:

if s[ind]=='0':
    dp[ind][1] = dp[ind][1]+1 
else:
    dp[ind][0] = dp[ind][0]+1

初始条件为:

if s[0]=='0':
    dp[0][1] = dp[0][1]+1 
else:
    dp[0][0] = dp[0][0]+1

代码为:

class Solution:
    def minFlipsMonoIncr(self, s: str) -> int:
        n = len(s)
        dp = [[0,0] for _ in range(n)]
        if s[0]=='0':
            dp[0][1] = dp[0][1]+1 
        else:
            dp[0][0] = dp[0][0]+1

        for ind in range(1,n):
            dp[ind][0] = dp[ind-1][0] 
            dp[ind][1] =min(dp[ind-1][0],dp[ind-1][1])
            if s[ind]=='0':
                dp[ind][1] = dp[ind][1]+1 
            else:
                dp[ind][0] = dp[ind][0]+1
        return min(dp[n-1])    
            
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值