第三章作业
1.1 最优子结构,递归方程、定义、边界条件
问题描述回顾
N\times N网格,从左上角(1,1)走到右下角(N,N);只能上下左右走,必须恰好走 2N-1 步(意味着路径不能绕路,等价于:只能向右、向下移动,不能回头)。每个格子有费用,求路径最小总费用。
状态定义:
dp[i][j]:从起点(1,1)走到格子(i,j)的最小通行总费用。
递归方程式:
dp[i][j] = grid[i][j]+\min
\begin{cases}
dp[i-1][j] \quad \text{从上方来(上一行同列)}\
dp[i][j-1] \quad \text{从左方来(同行左边一列)}
\end{cases}
边界条件
1. dp[1][1] = grid[1][1]:起点,费用就是本身格子费用
2. 第一行(i=1,j>1):只能从左边过来
dp[1][j] = dp[1][j-1] + grid[1][j]
3. 第一列(j=1,i>1):只能从上方过来
dp[i][1] = dp[i-1][1] + grid[i][1]
最优子结构说明:到达(i,j)的最优路径,一定是到达上方(i-1,j)或者左方(i,j-1)的最优路径,再加上当前格子费用。子问题最优,原问题才最优
1.2 填表法:表维度、填表范围、填表顺序,原问题最优值位置
表维度:二维数组 dp[N+1][N+1](下标从1开始,N \le 100)
填表范围:i\in[1,N],\ j\in[1,N]
填表顺序:
1. 先填起点 dp[1][1]
2. 填第1行:从左向右 j=2 \to N
3. 填第1列:从上向下 i=2 \to N
4. 其余单元格:按行优先,i从2到N;每行内部j从2到N依次填充。计算dp[i][j]时,上方dp[i-1][j]、左边dp[i][j-1]都已经算好。
原问题最优值:\boldsymbol{dp[N][N]}(右下角单元格)
1.3 时间、空间复杂度
时间复杂度:O(N2),网格一共N2个单元格,每个单元格仅一次计算,每次取min是O(1)。
空间复杂度:O(N^2),使用二维dp数组存储所有子问题结果。
- 对动态规划算法的理解和体会
动态规划核心思想是拆分大问题为重叠子问题,利用最优子结构,记录子问题答案避免重复计算。
本题中,暴力搜索会重复计算很多到达同一格子的路径开销,效率很低。动态规划用一张dp表保存到达每个位置的最小费用,每个子问题只求解一次。
动态规划解题关键三步:
1. 定义状态,清晰描述子问题含义;
2. 推导状态转移方程,找出子问题之间依赖;
3. 确定边界条件与填表顺序,保证计算子问题时,依赖的前置结果已经算出。
动态规划适合具有最优子结构+重叠子问题的问题;它本质是以空间换时间,存储中间结果,减少重复递归计算。

浙公网安备 33010602011771号