动态规划学习总结

本文总结了动态规划的学习心得,包括基础动态规划、背包问题(01背包和完全背包)、打家劫舍问题、股票问题及子序列问题。通过实例解析递推公式、初始化、状态存储,帮助理解动态规划的解决思路。
摘要由CSDN通过智能技术生成

本文结合 代码随想录 + leetcode官方解答,做了学习和总结,仅个人记录学习。

代码随想录网址代码随想录

动态规划大致分为以下几个问题:

1.基础动态规划

2.背包问题

3.打家劫舍

4.股票问题

5.子序列问题

1.基础动态规划

基础使用场景:多为计算最少个数,返回一般为一个整数
解决基本思路:
1考虑前一个状态和该状态的影响关系(递推公式)
2注意起始状态(初始化)
3考虑遍历时需要的基础存储量(如数组,变量),决定了循环的层数

2.背包问题

2.1    01背包问题

2.1.1基础背包问题

问题:背包总承重量、物品重量+物品价值,每个物品最多取1次,求背包装载最大价值。
解法:二维数组,dp[i][j],i表示物品,j表示0-m(m为背包承受的最大重量),dp[i][j]表示j重量下前          i 个物品所能达到的最大价值。
     横向遍历:前i个物品所能装载到该重量下的最大价值。
     赋值:第i个物品在j重量下只有两个状态,要么装要么不装,所以只用对两个值比较选最大
                不装:为dp[i-1][j]的值
                装:为dp[i-1][j-w]的值
                比较后取最大值。
     结果:取dp[i][j]

eg.)

 2.1.1变种背包

问题:从数据集中选出部分数,使这些数总和达到某个值n,数据集中的每个数最多取1次。
解法:二维数组,dp[i][j],i表示数字,j表示0-n(n为到达值),dp[i][j]表示j数值下前i个数是否能

           到达该值,为bool。
           关键不同点为dp[i][j]为bool值,核心为是否能到达这个值。
           判断方式和01背包相同,要么取值,要么不取值。
                      即 取:dp[i-1][j-n[I]]为true,则为true
                           不取:dp[i-1][j]为true,则为true

 优化:

    dp[0] = true
    for _, weight := range stones {
        for j := m; j >= weight; j-- {
            dp[j] = dp[j] || dp[j-weight]
        }
    }

目标和中,dfs可以解决,但复杂度高。考虑前一状态是否会影响到现状态,发现确实有影响,再考虑变化情况:

 

图片摘自力扣

 因为数组下标从0开始,所以对整个数组计数进行了偏移,即向右平移sum个单位。

 把数值变量变化为了数组,比如之前的是0,1,2,3,现在变为了[0,0],[0,1],[1,0]...[5,3]

总结:

背包一般能解决的问题:

(1)能到达的最大值(返回int)

(2)是否能到达该值(返回bool)

(3)到达该值的种数(返回int)

2.2 完全背包

和01背包问题相比,物品选择的次数是0次和多次。其余部分和01背包问题来说没有什么大差别。

新物品放入最新状态,可以影响后一状态,体现在循环的时候可以从小到大遍历。

 下题中,排列顺序影响数值结果,考虑递推规律:

以4为示例:

最后一次选1,则为剔除选择1的所有情况,到达4-1=3的所有情况

最后一次选2,到达4-2=3的所有情况

最后一次选3,到达4-3=1的所有情况

则4的所有可能性为,dp[3]+dp[2]+dp[1]

比较最小情况,初始化赋值为amount+1

 

通过是否达到下标进行问题转换。 

3打家劫舍系列

 

4股票系列

121. 买卖股票的最佳时机

122. 买卖股票的最佳时机 II

714. 买卖股票的最佳时机含手续费

123. 买卖股票的最佳时机 III

188. 买卖股票的最佳时机 IV

309. 最佳买卖股票时机含冷冻期

 如 5位置,持有状态即要么买要么不买,买为-5,不买为原值-1

                  不持状态即要么卖要么不卖,卖为5-1,不卖为0.

                   均取最大值保存

其实也类似贪心,持有的时候保存最小买入值,卖出的时候保存最大卖出值。

第一题仅能卖一次,第二题能够卖多次,所以主要不同为,卖的过程中必须把之前买的卖掉才能购买。 

 买卖多次状态中再增加一个交易费用,即卖出状态下-fee

 设置四个状态,第一次买入,第一次卖出,第二次买入,第二次卖出。

第一次买入选价格最低点;第一次卖出为当前价格+第一次买入价格;第二次买入为第一次卖出持有收益-当前价格;第二次卖出为当前价格+第二次买入持有收益。

 和上一题相比,唯一的不同是次数限制不止为两次,交易一次,分为买入/持有,卖出/持有两种状态,所以状态数增加到2*k种,为增加普适度,添加dp[0]=0状态。

出现冷冻状态,增加冷冻状态、非冷冻持有状态。

买入状态的值影响的有:冷冻状态买入、非冷冻状态买入、原买入状态

卖出状态:买入状态+物价

非冷冻持有状态值变化:原非冷冻、冷冻

冷冻状态:买入状态。

5子序列问题

 300. 最长递增子序列详解

感觉上面的链接讲得很细,贴一个

 因为同一个字符只能算一个,所以需要和斜对角的数进行比较ˇ

视频图解 动态规划 最长公共子序列

 换了个描述,解法和上一题完全一致

 

连续子数组转换为二维数组,需要和斜对角数进行比较。 

和不相交的线 、最长公共子序列解法一致。

做多了动态规划可能会被某几个定式给框住,这时候需要会归到最简单的情况,从一两个字符开始分析问题,并且把所有方案给列出来进行思考。

上题的详细解析编辑距离图解

上述为暴力解法

上述为动态规划解法

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值