📅  最后修改于: 2023-12-03 15:27:26.346000             🧑  作者: Mango
这是一道关于算法的测验问题,属于SP竞赛的第三个问题。本问题需要程序员熟悉搜索算法和动态规划算法。
给定一个 $n \times m$ 的矩阵,矩阵中的每个元素都是非负整数。从第一行第一个元素开始出发,每次只能向右或者向下走,目标是到达最后一行最后一个元素,使得经过的路径上的数字之和最小。
第一行包含两个整数 $n, m$。
接下来 $n$ 行,每行 $m$ 个整数,表示矩阵中的元素。
一个整数,表示满足要求的使经过的路径上的数字之和最小的路径数字之和。
3 3
1 3 1
1 5 1
4 2 1
7
对于这道题目,我们可以利用动态规划算法来解决。我们定义 $f[i][j]$ 表示从 $(1,1)$ 到 $(i,j)$ 的最小路径和,则有状态转移方程:
$$ f[i][j]=\min(f[i-1][j],f[i][j-1])+a[i][j] $$
其中 $a[i][j]$ 表示第 $i$ 行,第 $j$ 列的元素。我们可以根据这个动态规划方程来求解最小路径和。
另外,我们也可以利用Dijkstra算法来解决该问题。可以将每个格子看成一个节点,每个节点之间的边权为两个节点值的和。这样就可以构成一个图,利用Dijkstra算法求解最短路径。
动态规划的实现:
n, m = map(int, input().split())
a = []
for i in range(n):
a.append(list(map(int, input().split())))
f = [[0x7fffffff for j in range(m)] for i in range(n)]
f[0][0] = a[0][0]
for i in range(n):
for j in range(m):
if i > 0:
f[i][j] = min(f[i][j], f[i-1][j]+a[i][j])
if j > 0:
f[i][j] = min(f[i][j], f[i][j-1]+a[i][j])
print(f[n-1][m-1])
Dijkstra算法的实现:
import heapq
n, m = map(int, input().split())
a = []
for i in range(n):
a.append(list(map(int, input().split())))
g = [[] for i in range(n*m)]
for i in range(n):
for j in range(m):
x = i * m + j
if i < n-1:
y = (i+1)*m+j
g[x].append((y, a[i+1][j]))
g[y].append((x, a[i][j]))
if j < m-1:
y = i*m+j+1
g[x].append((y, a[i][j+1]))
g[y].append((x, a[i][j]))
dist = [0x7fffffff for i in range(n*m)]
dist[0] = a[0][0]
heap = [(dist[0], 0)]
while heap:
d, x = heapq.heappop(heap)
if dist[x] < d:
continue
for t in g[x]:
y, w = t
if dist[y] > dist[x] + w:
dist[y] = dist[x] + w
heapq.heappush(heap, (dist[y], y))
print(dist[n*m-1])