剑指Offer-47 礼物的最大价值

题目:

在一个m×n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向左或者向下移动一格直到到达棋盘的右下角。给定一个棋盘及其上面的礼物,请计算你最多能拿到多少价值的礼物?
样例:
输入:
[
[2,3,1],
[1,7,1],
[4,6,1]
]
输出:19
解释:沿着路径 2→3→7→6→1 可以得到拿到最大价值礼物。
在线做题: https://www.acwing.com/problem/content/56/

解答:

动态规划,自顶向下进行思考,为避免计算重复子问题,实现时用自下而上的方法

  • 第一种实现方法:自顶向下进行递归,同时保存每个小矩阵的value
class Solution(object):
    def getMaxValue(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """
        self.d = {}
        m = len(grid)
        if m == 0:
            return
        if len(grid[0]) == 0:
            return
        else:
            n = len(grid[0])
        return self.getValue(grid, 0, 0, m, n)
        
    def getValue(self, grid, i, j, m, n):
        if i == m - 1:
            sum = 0
            for jj in range(j, n):
                sum += grid[i][jj]
            return sum
        if j == n - 1:
            sum = 0
            for ii in range(i, m):
                sum += grid[ii][j]
            return sum
        v = grid[i][j] + max(self.d.get((i + 1, j), self.getValue(grid, i + 1, j, m, n)), self.d.get((i, j + 1), self.getValue(grid, i, j + 1, m, n)))
        return v

然而这种方法运行超时。

  • 第二种方法:自下向上进行循环实现,剑指Offer提供了另一种实现方式,可以把二维数组优化为只用一维数组
class Solution(object):
    def getMaxValue(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """
        m = len(grid)
        if m == 0:
            return
        if len(grid[0]) == 0:
            return
        else:
            n = len(grid[0])
        iplusj = m - 1 + n - 1
        result = [[0 for i in range(n)] for j in range(m)]
        while(iplusj >= 0):
            for i in range(iplusj + 1):
                j = iplusj - i
                if i >= m or j >= n or i < 0 or j < 0:
                    continue
                else:
                    if i == m - 1 and j == n - 1:
                        result[i][j] = grid[i][j]
                        continue
                    if i == m - 1:
                        result[i][j] = grid[i][j] + result[i][j + 1]
                        continue
                    if j == n - 1:
                        result[i][j] = grid[i][j] + result[i + 1][j]
                        continue
                    result[i][j] = grid[i][j] + max(result[i][j + 1], result[i + 1][j])
                    continue
            iplusj -= 1
        return result[0][0]   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值