LC每日一题|20240507 - 1463. 摘樱桃 II

95 阅读3分钟

LC每日一题|20240507 - 1463. 摘樱桃 II

给你一个 rows x cols 的矩阵 grid 来表示一块樱桃地。 grid 中每个格子的数字表示你能获得的樱桃数目。

你有两个机器人帮你收集樱桃,机器人 1 从左上角格子 (0,0) 出发,机器人 2 从右上角格子 (0, cols-1) 出发。

请你按照如下规则,返回两个机器人能收集的最多樱桃数目:

  • 从格子 (i,j) 出发,机器人可以移动到格子 (i+1, j-1)(i+1, j) 或者 (i+1, j+1) 。
  • 当一个机器人经过某个格子时,它会把该格子内所有的樱桃都摘走,然后这个位置会变成空格子,即没有樱桃的格子。
  • 当两个机器人同时到达同一个格子时,它们中只有一个可以摘到樱桃。
  • 两个机器人在任意时刻都不能移动到 grid 外面。
  • 两个机器人最后都要到达 grid 最底下一行。

提示:

  • rows == grid.length
  • cols == grid[i].length
  • 2 <= rows, cols <= 70
  • 0 <= grid[i][j] <= 100 

题目等级:Hard

解题思路

u1s1,最初刚看到这个血淋淋的Hard的时候,我是非常崩溃的。

五月才过了7天,LC就已经出了4个Hard了,而且其中还有三道dp...这tm让人怎么活呀TvT

冷静下来一看题目,嘿嘿,tm这不就是昨天那道题吗,换汤不换药,甚至更简单了一点...

LC每日一题|20240506 - 741. 摘樱桃

我们开辟一个三维数组 dp[i][j][k],代表两个机器人分别从起点走到 [i][j][i][k]格子时所摘取的樱桃总数。

然后我们需要考虑两件事儿

  • 对于单个机器人来说,[x][y]是由谁转移来的?

    是由合法[x - 1][y - 1], [x - 1][y], [x - 1][y + 1]中的最大值 + grid[x][y]得到的。

  • 如果两个机器人同时走到同一个格子了怎么办?

    那就是 j == k 的情况了。如果 j != k,两个机器人分别拾取自己格子里的;反之如果遇到一起,就只对这个格子拾取1次就好了。

最终返回dp表里的最大值就可以啦~

(这次就先不考虑空间优化的问题咯~

AC代码

class Solution {
    fun cherryPickup(grid: Array<IntArray>): Int {
        val dp = Array<Array<IntArray>>(grid.size) { Array<IntArray>(grid[0].size) { IntArray(grid[0].size) { Int.MIN_VALUE } } }
        dp[0][0][grid[0].size - 1] = grid[0][0] + grid[0].last()
        var max = 0
        for (i in 1 until grid.size) {
            for (j in 0 until grid[0].size) {
                for (k in 0 until grid[0].size) {
                    var pre = dp[i - 1][j][k]
                    if (j > 0 && k > 0) pre = Math.max(dp[i - 1][j - 1][k - 1], pre)
                    if (j > 0) pre = Math.max(dp[i - 1][j - 1][k], pre)
                    if (k > 0) pre = Math.max(dp[i - 1][j][k - 1], pre)
                    if (j < grid[0].size - 1 && k < grid[0].size - 1) pre = Math.max(dp[i - 1][j + 1][k + 1], pre)
                    if (j < grid[0].size - 1) pre = Math.max(dp[i - 1][j + 1][k], pre)
                    if (k < grid[0].size - 1) pre = Math.max(dp[i - 1][j][k + 1], pre)
                    if (k < grid[0].size - 1 && j > 0) pre = Math.max(dp[i - 1][j - 1][k + 1], pre)
                    if (j < grid[0].size - 1 && k > 0) pre = Math.max(dp[i - 1][j + 1][k - 1], pre)
                    dp[i][j][k] = pre + grid[i][j]
                    if (j != k) dp[i][j][k] += grid[i][k]
                    max = Math.max(dp[i][j][k], max)
                }
            }
        }
        return max
    }
}

定义 m = grid.size, n = grid[0].size

时间复杂度:O(mn^2)

空间复杂度:O(mn^2)