题目:棋盘如下,每个棋盘的代价不同,每次只能向下走或者向右走,以最小的代价从左上角走到右下角,记录走的路径,该怎么走?
分析:
1. 关于怎么走
1). 第一行的棋格,除了第一个棋格,都是它左边的棋格向右走得到的。
2). 第一列的棋格,除了第一个棋格,都是它上边的棋格向下走得到的。
3). 棋盘中的剩余的棋格,要么从左边,要么从上边走过来,到底从哪过来,就要看这二者的大小.
4). dp
记录代价。dp[i][j]
走到(i,j)的最小代价
2. 关于路径记录
1). location
数组用来记录走到当前位置的上一步在哪。比如(1,1)的5从(1,0)的2走过来,所以location[1][1]=[1,0]
2). 当location
数组填完后,需要根据右下角元素回溯,找到最短路径。
3). location[i][j]
到达(i,j)的上一步在哪
import numpy as np
'''
走棋盘,每个棋盘的代价不同,以最小的代价从左上角走到右下脚,记录走的路径。
dp[i][j]走到(i,j)的最小代价
location[i][j]到达(i,j)的上一步在哪
'''
arr = np.array([[10,3,1],[2,8,5],[20,7,12]])
dp=np.zeros(arr.shape)
location=[[ 0 for i in range(3)]for j in range(3)]# 数组形式。numpy数组不能赋列表
location[0][0]=[0,0]
# print(location)
dp[0][0]=arr[0][0]
n = arr.shape[0]# 行数
m = arr.shape[1]# 列数
for i in range(m-1):
dp[0, i+1] = dp[0, i]+arr[0, i+1]
location[0][i+1]=[0,i]
for i in range( n- 1):
dp[i+1, 0] = dp[i, 0]+arr[i+1, 0]
# location[i+1][0].append([i, 0])
location[i+1][0]=[i, 0]
for i in range(1,n):
for j in range(1,m):
if dp[i-1][j] < dp[i][j-1]:
dp[i][j] = dp[i - 1][j]+ arr[i][j]
# location[i][j]=append([i-1,j])
location[i][j]=[i-1,j]
else:
dp[i][j] = dp[i][j- 1] + arr[i][j]
location[i][j]=[i,j- 1]
# dp[i][j]=min(dp[i-1][j],dp[i][j-1])+arr[i][j]
print('总代价为:',dp[2][2])
print('代价矩阵:\n',dp)
# print(location)
# print(location[2][2])
n = len(location)-1
m = len(location[0])-1
l = []
l.append([n, m])
while not(n==0 and m==0):
a = location[n][m]
# print(location[n][m])
n=location[n][m][0]
m=location[n][m][1]
l.append([n, m])
# print(n,m)
l.reverse()# 遍历顺序
print('走的路径为:')
for i,loc in enumerate(l):
if i == len(l)-1:
print(loc)
break
print(loc,end='——>')
总代价为: 31.0
代价矩阵:
[[10. 13. 14.]
[12. 20. 19.]
[32. 27. 31.]]
走的路径为:
[0, 0]——>[0, 1]——>[1, 2]——>[2, 2]