算法第三章作业

“7-4 最低通行费”动态规划实践报告

一个商人穿过一个N×N的正方形的网格,去参加一个非常重要的商务活动。他要从网格的左上角进,右下角出。每穿越中间1个小方格,都要花费1个单位时间。商人必须在(2N-1)个单位时间穿越出去。而在经过中间的每个小方格时,都需要缴纳一定的费用。
这个商人期望在规定时间内用最少费用穿越出去。请问至少需要多少费用?
注意:不能对角穿越各个小方格(即,只能向上下左右四个方向移动且不能离开网格)。

1.1 递归方程、定义与边界条件

定义:

[dp[i][j]]
表示从左上角 ((1,1)) 走到格子 ((i,j)) 时,所需缴纳的最少通行费,且费用包含起点和当前格子的费用。
对于内部格子 ((i,j)),即 (i\geq2,\ j\geq2),到达该格子只可能来自:

  • 上方格子 ((i-1,j));
  • 左侧格子 ((i,j-1))。
    因此递归方程为:
    [dp[i][j]=\min(dp[i-1][j],dp[i][j-1])+a[i][j]]
    边界条件如下:
    [dp[1][1]=a[1][1]]
    第一行只能从左向右到达:
    [dp[1][j]=dp[1][j-1]+a[1][j],\quad 2\leq j\leq N]
    第一列只能从上向下到达:
    [dp[i][1]=dp[i-1][1]+a[i][1],\quad 2\leq i\leq N]
    原问题的最优解为:
    [dp[N][N]]
    即从左上角到右下角所需的最少通行费。

1.2 填表法设计

动态规划表 dp 是一个二维数组,维度为:
[N \times N]
程序中采用下标从 1 开始的写法,因此定义为 dp[105][105],可满足题目 (N<100) 的要求。
填表范围及顺序如下:

  1. 先填左上角:dp[1][1];
  2. 从左到右填第一行:dp[1][2] 至 dp[1][N];
  3. 从上到下填第一列:dp[2][1] 至 dp[N][1];
  4. 按行优先顺序填其余位置:外层循环 (i=2) 到 (N),内层循环 (j=2) 到 (N)。
    这种顺序保证计算 dp[i][j] 时,所需的 dp[i-1][j] 和 dp[i][j-1] 都已经求出。
    最终,表中右下角元素:
    [dp[N][N]]
    就是商人在规定时间内穿越网格的最少通行费。

1.3 时间复杂度和空间复杂度

共有 (N^2) 个状态,每个状态只进行一次取最小值和加法运算,均为常数时间,因此时间复杂度为:
[O(N^2)]
程序使用了费用数组 a 和动态规划数组 dp,二者均为二维数组,所占空间与网格规模成正比,因此空间复杂度为:
[O(N^2)]
若不要求保留完整的动态规划表,还可以使用一维数组滚动更新,将动态规划部分的空间降为 (O(N));但题目给出的代码采用二维表,故其实际空间复杂度为 (O(N^2))。

posted @ 2026-11-01 18:49  Tracy__cc  阅读(4)  评论(0)    收藏  举报