第三章作业
算法第三章实践报告
这题一开始看“必须在 2N-1 个单位时间出去”有点懵,其实 N×N 网格从左上到右下,最短就是走 2N-1 个格子,所以商人不能绕路,只能向右或向下走。这样题目就变成了:从左上走到右下,每次只能往右或往下,求最小费用路径和。
- 动态规划分析
1.1 递归方程式和边界条件
定义 dp[i][j] 表示从左上角 (1,1) 走到 (i,j) 的最小费用。
因为只能从上面或左边过来,所以:
dp[i][j] = a[i][j] + min(dp[i-1][j], dp[i][j-1])
其中 a[i][j] 是格子 (i,j) 的费用。
边界条件:
· dp[1][1] = a[1][1]
· 第一行只能从左边来:dp[1][j] = dp[1][j-1] + a[1][j]
· 第一列只能从上边来:dp[i][1] = dp[i-1][1] + a[i][1]
1.2 填表法
表的维度:二维表,大小是 N × N。
填表范围:i 从 1 到 N,j 从 1 到 N。
填表顺序:按行从上到下填,每一行从左到右填。因为 dp[i][j] 只依赖上面和左边,所以这个顺序能保证用到的值已经算好。
原问题的最优值就是 dp[N][N],也就是从左上角到右下角的最小费用。
1.3 复杂度
时间复杂度:每个格子算一次,每次常数时间,所以是 O(N²)。
空间复杂度:开了 N×N 的 dp 表,所以是 O(N²)。其实也可以滚动数组优化到 O(N),但按填表法写就是 O(N²)。
- 对动态规划的理解和体会
动态规划感觉就是先把大问题拆成小问题,把算过的结果存起来,后面直接用,避免重复计算。这题关键是想清楚状态 dp[i][j] 表示什么,然后找到它和上面、左边的转移关系。还有那个 2N-1 的时间限制,其实是在暗示只能向右或向下走,不然就会超时。总的来说,动态规划不难在代码,难在状态定义和转移方程,想明白了写起来就挺顺的。

浙公网安备 33010602011771号