返回

用动态规划算法解决 leetcode 1463. Cherry Pickup II(python)

后端

作为一名经验丰富的技术博客撰写专家,我乐于分享我对 LeetCode 1463 的见解:Cherry Pickup II(python)。凭借我构建见解独特且引人入胜的文章的能力,我将为您提供一个引人入胜且全面的指南,让您掌握这种动态规划算法。

简介

LeetCode 1463:Cherry Pickup II 是一道算法难题,要求我们在网格中收集樱桃,同时还要考虑收集器路径和移动限制。为了解决这个问题,我们使用动态规划算法,这是一种强大的技术,可以将复杂问题分解成较小的子问题。

方法

在我们的动态规划算法中,我们将网格状态定义为收集器 1 和收集器 2 的当前位置和樱桃收集数。我们采用自底向上的方法,从网格的左下角开始,逐步填充状态表。

第一种方法:基础动态规划

我们的基础动态规划算法从网格的左下角开始,逐行逐列地填充状态表。对于每个状态,我们考虑收集器 1 和收集器 2 的所有可能移动,并选择使总樱桃收集数最大的移动。

第二种方法:记忆化搜索

为了优化我们的算法,我们采用记忆化搜索技术。我们使用一个哈希表来存储已计算的状态,从而避免重复计算。这可以显著提高算法的效率,尤其是对于较大的网格。

第三种方法:滚动数组

作为进一步的优化,我们使用滚动数组技术。我们只存储当前行和上一行的状态,而不是整个状态表。这可以大大减少内存使用量,尤其是在处理大型网格时。

示例代码(python)

def cherryPickup(grid):
    m, n = len(grid), len(grid[0])
    dp = [[[-1] * (m + n) for _ in range(m)] for _ in range(n)]
    return cherryPickupDP(grid, 0, 0, 0, 0, dp)

def cherryPickupDP(grid, r1, c1, r2, c2, dp):
    if r1 == len(grid) or c1 == len(grid[0]) or r2 == len(grid) or c2 == len(grid[0]) or grid[r1][c1] + grid[r2][c2] == -1:
        return -1e9
    if dp[r1][c1][c2 - r1] != -1:
        return dp[r1][c1][c2 - r1]
    res = grid[r1][c1]
    if r1 == r2 and c1 == c2:
        res += grid[r2][c2]
    else:
        res += grid[r2][c2]
    a = cherryPickupDP(grid, r1 + 1, c1, r2 + 1, c2, dp)
    b = cherryPickupDP(grid, r1, c1 + 1, r2 + 1, c2, dp)
    c = cherryPickupDP(grid, r1 + 1, c1, r2, c2 + 1, dp)
    d = cherryPickupDP(grid, r1, c1 + 1, r2, c2 + 1, dp)
    res += max(a, b, c, d)
    dp[r1][c1][c2 - r1] = res
    return res

优点

动态规划算法解决 LeetCode 1463:Cherry Pickup II 具有以下优点:

  • 清晰简洁:算法易于理解和实现。
  • 高效:通过采用优化技术,该算法可以有效地处理大型网格。
  • 通用性:动态规划算法可以解决各种类型的优化问题。

结论

利用动态规划算法解决 LeetCode 1463:Cherry Pickup II 是一种有效而多才多艺的方法。通过采用基础动态规划、记忆化搜索和滚动数组技术,我们可以优化算法以获得最佳性能。掌握这种算法将极大地提升您解决此类问题的技能,并为您解决更复杂的算法难题做好准备。