第三章作业
最低通行费 动态规划分析报告
题目核心条件梳理:N×N网格,起点(1,1)在左上角,终点(N,N)在右下角;只能上下左右移动;必须在2N-1个时间内到达。每穿过一个小方格耗时1个时间单位,2N-1个时间意味着路径只能向右、向下走,不能回头(即不能向左、向上)。理由如下:从(1,1)到(N,N),最少步数就是向右N-1次加向下N-1次,一共2N-2步,恰好经过2N-1个格子;一旦向上或向左移动,总步数就会超过2N-1,必然超时。所以合法路径等价于只向右、向下移动。
1.1 递归方程、状态定义与边界条件
(1)状态定义
设dp[i][j]表示从起点(1,1)走到格子(i,j)所需的最小总通行费。
设a[i][j]表示格子(i,j)本身的费用。
(2)最优子结构分析
要到达格子(i,j),只可能来自两个位置:一是上方格子(i-1,j),向下走一步过来;二是左方格子(i,j-1),向右走一步过来。取这两条路径费用的最小值,再加上当前格子(i,j)的费用,就得到dp[i][j]。
(3)递归方程
dp[i][j] = min( dp[i-1][j] , dp[i][j-1] ) + a[i][j]
(4)边界条件
第一,起点:dp[1][1] = a[1][1],即起点只有自身的费用。
第二,第一行(i=1,j>1):上方没有格子,只能从左边的格子过来,所以 dp[1][j] = dp[1][j-1] + a[1][j]。
第三,第一列(j=1,i>1):左边没有格子,只能从上方的格子过来,所以 dp[i][1] = dp[i-1][1] + a[i][1]。
说明:题目限制2N-1时间,天然屏蔽了向上、向左的路径,因此状态转移中不需要额外判断是否超时,转移方程本身就满足时间约束。
1.2 填表维度、填表范围、填表顺序与原问题最优值
(1)表的维度
使用二维数组 dp[N+1][N+1],下标从1开始,方便处理边界,避开下标0。
(2)填表范围
i从1到N,j从1到N,即整张N×N的表都要填。
(3)填表顺序
按行优先顺序填表,即从上到下、每行内部从左到右。具体为:先填第一行,再填第一列;随后依次遍历i=2,3,到N,对每一个i,j从2到N。这样能保证计算dp[i][j]时,它依赖的上方dp[i-1][j]和左方dp[i][j-1]都已经算好。也可按斜对角线(同一步数层)填表,但行优先最简单,适合本题。
(4)原问题最优值
原问题的最优值就是 dp[N][N],即走到右下角终点所需的最小总费用。
1.3 时间复杂度和空间复杂度
(1)时间复杂度:O(N的平方)
一共有N乘N个状态,每个状态只做一次min比较和一次加法,都是常数操作。题目中N小于100,规模很小。
(2)空间复杂度
使用朴素二维dp时,需要N乘N的dp表,复杂度为O(N的平方);可以优化为滚动数组,压缩到一维,复杂度降为O(N)。考试作答一般写二维即可。
二、对动态规划算法的理解和体会
动态规划的核心是把大问题拆分成互相重叠的子问题,利用最优子结构和无后效性,避免暴力枚举所有路径。本题如果暴力搜索,会枚举大量路径,随着N增大路径数量会指数爆炸;而动态规划把每个位置的最优解记录下来,每个位置只需计算一次。
本题的关键点,是读懂时间限制背后隐藏的移动约束:题目表面上允许上下左右四个方向移动,实际上因为时间限制,只能向右和向下走,这才确定了状态转移的来源只有两个。
本题体现的最优子结构是:走到(i,j)的最优路径,一定由走到上方格子或左方格子的最优路径延伸而来。体现的无后效性是:dp[i][j]只依赖左边的格子、上边的格子,不关心之前具体是怎么走过来的。
填表顺序非常关键,必须保证当前格子依赖的格子已经先计算完成。总的来说,动态规划的本质是用空间换时间,把子问题的答案存起来重复利用,从而降低时间复杂度。做题时不能直接套公式,要先挖掘题目里隐藏的约束条件,再定义状态,再写出转移方程。

浙公网安备 33010602011771号