方格取数(python)
思路
最关键的是分为两类,一类是从上往下和从从左向右取最大值,一类是从下往上和从左往右取最大值,所以每个f[i][j]有两次更新,一次是从下往上,一次是从上往下
python 代码 $O(nm)$
#状态表示:从f[1][1]到f[i][j]向上、向下或向右且下一步向右的所有集合(这里向右是因为,一个位置只有四种放向,列举了上下左三个方向,就只剩向右一个方向了)
#状态计算:s=max(s,f[i][j-1])+shu[i-1][j-1],f[i][j]=max(f[i][j],s)
#这里有个小细节得注意,初始化一定要赋值为无穷大,有个测试点的开头一列为负数,如果赋值为0就会把开头的这一列负数给自动忽略
n,m=map(int,input().split())
shu=[]
for i in range(n):
shu.append([int(i) for i in input().split()])
f=[[float('-inf') for i in range(m+1)] for j in range(n+1)]
f[1][0]=0
for j in range(1,m+1):
s=float('-inf')
for i in range(1,n+1):
#找到上一个节点的最大值,然后再加上该节点即是这个节点的最大值(新算出的值)
s=max(s,f[i][j-1])+shu[i-1][j-1]
#更新f[i][j],这里会有从上往下,和从下往上两个方向,因此这里要设置一个f[i][j]和新算出的值做一个更新
f[i][j]=max(s,f[i][j])
s=float('-inf')
for i in range(n,0,-1):
s=max(s,f[i][j-1])+shu[i-1][j-1]
f[i][j]=max(s,f[i][j])
print(f[n][m])