走棋盘——最小代价

题目:棋盘如下,每个棋盘的代价不同,每次只能向下走或者向右走,以最小的代价从左上角走到右下角,记录走的路径,该怎么走?
在这里插入图片描述

分析:
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]
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值