题目来源都是LeetCode。
目录
动态规划
动态规划属于运筹学范畴,是求解决策过程最优化的过程。动态规划算法求解时,需将待求解问题分解成若干个子问题,先求解子问题的解,然后从子问题的解推导出原问题的解。也就是说,大规模问题的解是由小规模问题的解运算得到的。
动态规划应用条件
- 无后效性:某阶段的状态确定后,就不会受到该阶段之后的后续决策的影响;
- 重叠子问题:存在重复子问题,子问题的解会被多次利用;
- 最优子结构:原问题在获得最优解的情况下,由原问题分解出来的子问题,在各自的规模上,也是最优解。分解得到的子问题之间需要保持独立性,也就是说,下一状态的确定可由前面的状态推导出来。
动态规划应用考虑点
- 阶段划分
- 初始状态:动态规划的状态起点
- 转移方程:利用转移方程,可通过上一阶段的状态推断出当前阶段的状态;
- 边界条件:也即动态规划停止的条件或者一些限制条件
动态规划典型题目类型
- 求最优解问题,最大值和最小值。典型问题包括:最长回文子串、最长上升子序列等
- 求方案数。典型问题包括:路径规划,也就是常见的机器人走图的路径数
- 求是否可行,这种题目的结果通常为true或者false。典型问题包括:兑换零钱问题等
动态规划例题
题1:能拿到的礼物的最大价值
在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?
输入:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
输出: 12
解释: 路径 1→3→5→2→1 可以拿到最多价值的礼物
动态规划代码如下:
class Solution {
public int maxValue(int[][] grid) {
// 动态规划
int m = grid.length;//行数
int n = grid[0].length;//列数
int[][] f = new int[m][n];
int max = 0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
f[i][j] = 0;
}
}
f[0][0] = grid[0][0];
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(i==0 && j>0){//上边界
f[i][j] = f[i][j-1] + grid[i][j];
}else if(j==0 && i>0){//左边界
f[i][j] = f[i-1][j] + grid[i][j];
}else if(i!=0 && j!=0){//其它情况
f[i][j] = Math.max(f[i-1][j], f[i][j-1]) + grid[i][j];
}
max =

本文深入探讨了动态规划的概念,强调了其应用于解决优化问题的关键条件:无后效性、重叠子问题和最优子结构。通过分析动态规划的阶段划分、初始状态、转移方程和边界条件,文章列举了多个经典例题,包括求解最大价值问题、打家劫舍系列、最长回文子串、最长重复子数组以及不同路径的计算。动态规划在解决这些优化问题中展现出强大的能力,能够有效地找到最优解或计算方案数。
最低0.47元/天 解锁文章
862

被折叠的 条评论
为什么被折叠?



