算法第三章作业
- 实践报告
1.1 最优子结构与递归方程式
状态定义:定义 dp[i][j] 表示商人从网格左上角 (0, 0) 走到网格位置 (i, j) 时,所花费的最少通行费。
最优子结构性质:题目限制商人必须在 (2N-1) 个单位时间内穿越出去。从左上角 (0,0) 到右下角 (N-1, N-1),如果只能向右和向下移动,正好经过的方格数为 2N-1 个(步数正好)。这意味着商人不能走回头路(不能向左或向上)。因此,到达位置 (i, j) 的前一步只能是从其上方 (i-1, j) 或左方 (i, j-1) 走过来的。到达 (i, j) 的最少费用,取决于到达其上方或左方的最少费用加上当前格子的费用,这满足最优子结构性质。
递归方程式:
当 i == 0 && j == 0 时:dp[i][j] = cost[i][j] (起点)
当 i == 0 && j > 0 时(第一行):dp[i][j] = dp[i][j-1] + cost[i][j]
当 i > 0 && j == 0 时(第一列):dp[i][j] = dp[i-1][j] + cost[i][j]
当 i > 0 && j > 0 时:dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + cost[i][j]
边界条件:
输入网格大小N需满足 1≤N<100
第一行和第一列由于只有唯一路径(只能一直向右或一直向下),因此需单独进行累加初始化。
1.2 填表法分析
表的维度:二维数组表 dp[N][N]。
填表范围:i 从 0 到 N-1,j 从 0 到 N-1。
填表顺序:从上到下(行号 i 递增),从左到右(列号 j 递增)。因为计算 dp[i][j] 依赖于其上方 dp[i-1][j] 和左方 dp[i][j-1] 的值,所以必须按照这个顺序计算(即自底向上的方式)。
原问题的最优值:原问题要求从左上角到右下角的最少费用,因此最优值就是二维表格右下角的元素:dp[N-1][N-1]。
1.3 算法的时间和空间复杂度分析
时间复杂度:代码使用了两层嵌套的 for 循环遍历整个 N×N的网格,每个状态的计算(比较和加法)只需 O(1)的时间。因此,时间复杂度为 O(N²)。
空间复杂度:算法中使用了 cost[105][105] 来存储原网格数据,以及 dp[105][105] 来存储动态规划的状态值。两者的大小都取决于N,因此空间复杂度为 O(N²)。
- 对动态规划算法的理解和体会
动态规划是将一个复杂的原问题拆解成多个相互重叠的子问题,通过存储子问题的解,避免重复计算,从而高效地求解。
体会:1.要有严谨的边界处理,初始状态非常重要;2.合理的递推顺序,填表法必须保证“依赖项先于计算项得出”;3.局部最优与全局最优,每个格子都在做当前的最优决策,最终积累的结果自然就是全局最优。
浙公网安备 33010602011771号