📅  最后修改于: 2023-12-03 15:06:37.486000             🧑  作者: Mango
在计算机科学中,从矩阵的左上角到右下角的最小成本,是一种经典的算法问题,通常用于矩阵路径搜索和优化问题。
给定一个m x n的矩阵,矩阵中的每个元素都代表通过该位置的成本。从矩阵的左上角开始,只能向右或向下移动。到达矩阵的右下角的最小成本是多少?
例如,给定以下3 x 3的矩阵
[
[1, 3, 1],
[1, 5, 1],
[4, 2, 1]
]
从左上角到右下角的最小成本为7(1+3+1+1+1)。
最朴素的解决方案是暴力枚举,即枚举所有从左上角到右下角的路径。由于每个位置只能向右或向下移动,因此总路径数是 C(m+n,m) 。对于每条路径,都需要计算它的成本。由此可得,暴力枚举的时间复杂度为 O(C(m+n,m) * mn) ,显然在实际应用中不可行。
动态规划(Dynamic Programming,简称 DP)是一种高效的算法思想,可用于解决大部分优化问题,包括从矩阵的左上角到右下角的最小成本问题。
该问题可以用动态规划的思想描述为,先定义一个状态转移方程 dp[i][j] ,表示从矩阵的左上角到达 (i,j) 位置的最小成本。由此可得状态转移方程:
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + cost[i][j]
其中, cost[i][j] 是矩阵 (i,j) 位置的成本, dp[0][0] 为矩阵左上角的成本。
根据状态转移方程,可用递推的方式求得矩阵右下角的最小成本。代码如下:
def minCost(cost: List[List[int]]) -> int:
m, n = len(cost), len(cost[0])
dp = [[0] * n for _ in range(m)]
dp[0][0] = cost[0][0]
# 初始化第一列和第一行
for i in range(1, m):
dp[i][0] = dp[i-1][0] + cost[i][0]
for j in range(1, n):
dp[0][j] = dp[0][j-1] + cost[0][j]
# 递推求解
for i in range(1, m):
for j in range(1, n):
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + cost[i][j]
return dp[m-1][n-1]
该算法的时间复杂度为 O(mn) ,空间复杂度为 O(mn) 。由此可见,动态规划是一种高效的解决方法。
从矩阵的左上角到右下角的最小成本问题是一种经典的算法问题,常用于矩阵路径搜索和优化问题。暴力枚举虽然简单易懂,但时间复杂度太高。动态规划思想可以大幅度提高计算效率,是解决该问题的主流方法。