题目描述
在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?
输入:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
输出: 12
解释: 路径 1→3→5→2→1 可以拿到最多价值的礼物
思路分析
从最后一个元素(第m行第n列)开始,上一次的元素只可能从左边或者上面来。到底从哪个来呢?就比较当前元素 遍历到左边 的和遍历上面的,谁的累计加和最大。
1、原问题和子问题
原问题:m行n列,获取礼物的最大价值
子问题:任意第i行第j列,礼物的最大价值。其中0<= i <= m-1,0<= j <= n-1
2、状态
两个自变量(i,j),表示对二维列表的索引位置。
3、状态转移方程
(1)m = n = 1, f(m,n) = List[0][0]
(2)一行多列, m = 1, n !=1 , f(m,n) = 第一列元素之和
(3)多列一行, n = 1,m!= 1, f(m,n) = 第一行元素之和
(4)多行多列,m>1,n>1, f(m,n) = max(f(m-1,n), f(m,n-1)) + List[m][n]
代码实现
1、获取最大价值
def getmaxValue(numList):
m = len(numList) # m 行n列
n = len(numList[0])
if m == 1:
return sum(item[0] for item in numList)
if n == 1:
return sum(numList)
ans_list = [[-1]*n for i in range(m)] # 创建一个m行n列的空矩阵 DP数组
# 边界结果分析记录(只有一行或1列)
for i in range(n): # 矩阵的第一行元素
ans_list[0][i] = sum(numList