动态规划刷题日记

这篇博客探讨了使用动态规划解决三类经典问题:爬楼梯问题、寻找最大子序和以及确定最佳股票交易时机。博主首先介绍了每个问题的背景和初始解决方案,然后逐步优化,最终给出了高效动态规划算法。通过这些例子,博主总结了动态规划的核心思想,并强调了如何从问题中提炼前向状态来构建动态规划模型。

今天写动态规划~

爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1.  1 阶 + 1 阶
2.  2 阶
输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1.  1 阶 + 1 阶 + 1 阶
2.  1 阶 + 2 阶
3.  2 阶 + 1 阶

由于第n级台阶必须由n-1或n-2级到达,所以实际上n的方法数量就等于(n-1)级+(n-2)级,所以:

class Solution:
    def climbStairs(self, n: int) -> int:
        if n<3:return n
        i = 3
        sum1 = 1
        sum2 = 2
        total = 0
        while i <= n:
            total = sum1+sum2
            sum1 = sum2
            sum2 = total
            i += 1
        return total

最大子序和

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

一开始尝试直接写,让sum(n) = sum(n-1) + n这样一直往下累加,由于有负数,所以当sum(n)为负数时就可以不用往下累加了,因为对结果是消极的,就可以直接从当前位置开始重新累加

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        max = -999999
        sum = 0
        for num in nums:
            if sum >0:
                sum += num
            else:
                sum = num
            if sum>max:
                max = sum
        return max

买卖股票的最佳时机
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。

输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 没有交易完成, 所以最大利润为 0。

想了半天没思路,直接穷举....

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        i = 0
        profit = 0
        now = -1
        lowestPoint = 99999999
        plen = len(prices)
        while i<plen:
            if lowestPoint<prices[i]:
                i+=1
                continue
            max = -1
            now = prices[i]
            j = i+1
            while j<plen:
                if prices[j]>max:
                    max = prices[j]
                j+=1
            i+=1
            if max-now >profit:
                profit = max-now
                lowestPoint = now
        return profit

然而尽管做出了一些优化仍然爆时间,后来看到评论说:前i天的最大利润为max(第i天的最大利润,前i-1天的最大利润)。震惊乎,遂这样写:

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        i = 0
        profit = 0
        now = -1
        lowestPoint = 99999999
        plen = len(prices)
        while i<plen:
            lowestPoint = min(lowestPoint,prices[i])
            profit = max(prices[i]-lowestPoint,profit)
            i+=1
        return profit

记录最低点,每次循环刷新最低点和当前最大利润,诶过了嘿嘿~

这次写动态规划的好多题都莫得思路,总结后寻思是因为没有运用到动态规划的思想,以后想这类问题时可以尝试先求出前项,然后再一项项往里加。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值