第三章算法作业
- 实践报告
1.1 递推方程及边界条件
从左上角到右下角,需要向右走 N-1 步、向下走 N-1 步,加上起点,共经过 2N-1 个方格,正好用完规定时间。如果向左或向上走,就会绕路,无法按时到达。因此,实际只需要考虑向右和向下两种走法。
设 a[i][j] 表示第 i 行、第 j 列方格的费用,dp[i][j] 表示从起点走到该方格的最低总费用,包括起点和当前方格的费用。
到达 (i,j) 的前一步只能在上方或左方,所以只需比较这两个位置的最低总费用,取较小值,再加上当前方格的费用:
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + a[i][j]
其中,2 ≤ i,j ≤ N。
这里用到了最优子结构:如果到达当前方格的路径最优,那么到达它前一个方格的这段路径也必须最优,否则就能替换成更便宜的路径,使总费用更低。
边界条件:
- 起点:dp[1][1] = a[1][1]。
- 第一行只能从左边走过来,因此 dp[1][j] = dp[1][j-1] + a[1][j],2 ≤ j ≤ N。
- 第一列只能从上面走下来,因此 dp[i][1] = dp[i-1][1] + a[i][1],2 ≤ i ≤ N。
1.2 填表方法
dp 是一个二维表,有效大小为 N×N,下标范围为 1 ≤ i,j ≤ N。如果程序中的下标从1开始,可以开一个 (N+1)×(N+1) 的数组。
先填起点、第一行和第一列,再从第2行、第2列开始,按从上到下、每行从左到右的顺序填表。因为每个位置都要用到上方和左方的结果,这个顺序可以保证需要的数据已经算好。
样例填表结果如下:
行/列 1 2 3 4 5
1 1 5 11 19 29
2 3 8 15 30 46
3 9 16 24 42 62
4 19 27 36 55 76
5 39 50 61 84 109
最终答案保存在 dp[N][N] 中。样例中 dp[5][5] = 109,因此最低通行费为109。
1.3 时间和空间复杂度
一共需要计算 N×N 个位置,每个位置只进行一次比较和加法,所以时间复杂度为 O(N²)。
保存费用和计算结果都需要二维数组,所以空间复杂度为 O(N²)。
- 对动态规划算法的理解和体会
这道题首先要想清楚时间限制的作用。虽然题目说可以向四个方向移动,但规定时间只够走最短路线,所以不需要考虑向上和向左的情况。
写递推式时,可以先看“最后一步从哪里来”。本题中,最后一步只有上方和左方两种来源,比较它们的累计费用就能算出当前位置的结果。这里比较的是走到前一个方格的总费用,而不是前一个方格本身的费用。
我觉得做动态规划题时,要先说明数组中每个元素存的是什么,再确定递推关系和边界条件。状态的含义清楚了,填表顺序和最后取哪个位置作为答案也就容易确定了。

浙公网安备 33010602011771号