- 打家劫舍
- 最长子序列
- 背包问题
- 股票问题
方法论
注意:
- dp数组以及下标的含义
- 递推公式
- dp数组的初始化
- for循环的遍历顺序(先遍历背包,物品?i,j?)
动态规划
动态规划是解决多阶段决策问题的一种方法。动态规划是解决最优化问题的一种途径,但不是一种特殊算法,重点是一个建立状态转移方程的过程。
基本思想:
多阶段决策问题,如果一类问题的求解过程可以分为若干个互相联系的阶段,在每一个阶段都需作出决策,并影响到下一个阶段的决策。
动态规划的基本思路:
一、判断问题是否可以使用动态规划(判断问题是否具有最优子结构的性质)
二、把问题分成若干个子问题(分阶段)
三、建立状态转移方程(递推关系式)
四、找出边界条件。
五、将已知边界值带入方程。
六、递推求解。
**1**:计数
-计算有多少种方法走到右下角
-有多少种方法选出K个数使得和等于sum
**2**:求最值
-从左上角到右下角路径的最大数值和‘
-最长上升子序列长度
**3**:求存在性
-取石子游戏,先手能否获胜
-能否选出K个数使和为sum
简单斐波那契数列
背包问题
打家劫舍
打家劫舍 I 198
打家劫舍 II 213
打家劫舍 III 337
股票问题
买卖股票的最佳时机121
最佳买卖股票时机含冷冻期309
买卖股票的最佳时机含手续费 714
123、188 困难 pass
- dp[i][j]含义:下标为 i 这一天结束的时候,手上持股状态为 j 时,我们持有的现金数。j = 0,表示当前不持股;j = 1,表示当前持股。 int[][] dp = new int[len][2];
- 递推公式:(买入就-prices[i],卖出就+prices[i],不同的i,price不同 用max找最大值)
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
dp[i][1] = Math.max(dp[i - 1][1], -prices[i]);- 初始化: dp[0][0] = 0; dp[0][1] = -prices[0];
最长递增子序列
- 最优子结构,第i个最长递增子序列,最大子序和的最优子结构都是,前i个的最优,和第i个比较,
- dp[i],以下标为i的元素结尾的子序列长度
简单,一个for循环
- 两个for循环第二个用于找前i-1个位置 最长的序列长度
- dp[i]=Math.max(dp[j]+1,dp[i]);
二维数组路径问题
二维数组从左上到右下的路径数 62
二维数组从左上到右下的最小路径和 64
机器人的行走范围 剑指offer 13
剑指 Offer 47. 礼物的最大价值
其他
JZ48 最长不含重复字符的子字符串(不熟)
//dp[n]代表以数组下表为n位置结尾时 最长不重复子串,dp[0]=1,new dp[n]
s.charAt(j)!=s.charAt(i)
lc5最长回文子串