题目:在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于
0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多/少能拿到多少价值的礼物?
思路:动态规划。
倒着分析,有一个i*j的矩阵,最后一步,想要到达(i,j),要么从(i-1,j),要么从(i , j-1)。每一步遇到的问题相同,只不过不同的走法,得到的价值不一样。
f(i,j)=max(f(i,j-1)+f(i-1,j))+g(i,j) g(i,j)表示坐标为(i,j)的格子里礼物的价值
递归求解,会有大量的重复计算,通过递归分析,使用从下到上的循环求解(本题倒着分析,正着求解)
推到过程如下:
中间结果可直接保存到原数组中。
for循环,每次循环下一行/列,计算出每个位置的和,最大/最小价值使用max/min判断。
代码:
class Solution:
def func(self , array):
if len(array) <= 0 or array is None:
return 0
rows = len(array)
cols = len(array[0])
for i in range(rows):
for j in range(cols):
if i == 0 and j == 0:
continue
if i == 0:
array[i][j] += array[i][j -1]
elif j == 0:
array[i][j] += array[i -1][j]
else:
array[i][j] += max(array[i -1][j] , array[i][j-1]) # 最大价值,最小换成min即可
return array[rows-1][cols-1]
a = [[1,10,3,8] , [12,2,9,6] , [5,7,4,11] , [3,7,16,5]]
s = Solution()
print(s.func(a))