用python求最高和最低分_求矩阵最少(或最多)路径和(python实现)

1.递归方式

求最短,最终状态即右下角

f(v, i, j) = min(f(v, i - 1, j), f(v, i, j - 1)) + v[i][j]

最长只需将min改为max即可

import numpy as np

# i:行

# j:列

# v:矩阵

def f(v, i, j):

if i == 0 and j == 0:

return v[0][0]

elif i == 0:

return f(v, i, j - 1) + v[i][j]

elif j == 0:

return f(v, i - 1, j) + v[i][j]

else:

return min(f(v, i - 1, j), f(v, i, j - 1)) + v[i][j]

v = np.array([[1, 3, 5, 9], [8, 1, 3, 4], [5, 0, 6, 1], [8, 8, 4, 0]])

print(f(v, 3, 3))

2.递推方式

注意到只能往右或往下,可以想象,每下一层是右方或下方,而矩阵中,可以想象是以平行与对角线方向为一层,一层层从左上角到右下角递推

即运行一半为如此:

运行完全部为如此

而一层层,每层每一单元取左或上累计最少的数加上本身

f[i][j] = min(f[i - 1]f[j], f[i]f[j - 1]) + v[i][j]

因此:代码如下:

import numpy as np

# i:行

# j:列

# v:矩阵

def f(v, n):

s = np.array([[0] * n] * n)

for p in range(n):

for i in range(p + 1):

j = p - i

if i == 0 and j == 0:

s[0][0] = v[0][0]

elif i == 0:

s[0][j] = s[0][j - 1] + v[0][j]

elif j == 0:

s[i][0] = s[i - 1][0] + v[i][0]

else:

s[i][j] = min(s[i - 1][j], s[i][j - 1]) + v[i][j]

limit = 0

for p in range(n, 2 * n - 1):

limit += 1

for i in range(limit, p - limit + 1):

j = p - i

if i == 0 and j == 0:

s[0][0] = v[0][0]

elif i == 0:

s[0][j] = s[0][j - 1] + v[0][j]

elif j == 0:

s[i][0] = s[i - 1][0] + v[i][0]

else:

s[i][j] = min(s[i - 1][j], s[i][j - 1]) + v[i][j]

return s

v = np.array([[1, 3, 5, 9], [8, 1, 3, 4], [5, 0, 6, 1], [8, 8, 4, 0]])

print(f(v, 4))

最后统计出的矩阵的右下即为最少路径和(s[n-1][n-1])

而通过返回s[n-1],我们可以看到路径,从左上角开始,取每一层最小值(不可单独面对方向,可能会陷入陷阱,中途进入错误路径),代码实现如下:

def view(s, n):

string = ''

for p in range(n):

min = 0

for i in range(p + 1):

j = p - i

if min == 0:

min = s[i][j]

elif min > s[i][j]:

min = s[i][j]

string += str(min) + '->'

limit = 0

for p in range(n, 2 * n - 1):

limit += 1

min = 0

for i in range(limit, p - limit + 1):

j = p - i

if min == 0:

min = s[i][j]

elif min > s[i][j]:

min = s[i][j]

if p == (2 * n - 2):

string += str(min)

else:

string += str(min) + '->'

return string

原矩阵:

运行效果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值