Cherry Pickup解题心得

来源:互联网 发布:mac键盘pc机能用吗 编辑:程序博客网 时间:2024/05/21 01:46

Cherry Pickup解题心得

来源:https://leetcode.com/problems/cherry-pickup/description/

题目复述

输入一个n x n大小的地图,地图中的每个位置值包含三种值(-1, 0, 1),其中:

-1:代表不允许通过0:代表可以通过1:代表可以通过,而且路上有个Cherry(樱桃)

例如,输入:

 Input: grid =[[0, 1, -1], [1, 0, -1], [1, 1,  1]]

要求从[0, 0]出发到[n-1, n-1],要求只能向右或向下走,一路上收集樱桃,一个单位里的樱桃只能取走一次,如果取走则再次通过则为空;当到达[n-1, n-1]后再向左向上走回[0, 0],一路上同样收集樱桃
输出,求该过程(即从[0, 0]到[n-1, n-1],从[n-1, n-1]到[0, 0])最多可以获得多少樱桃
例如上输出的答案输出:

Output: 5

解题思路

  1. 最初思考的是实验动态规划计算,从[0, 0]到[n-1, n-1]的最大樱桃值,同时更新地图上经过有樱桃的位置为0,再从[n-1, n-1]到[0, 0]做一次一样的动态规划算法,则两次最优解的和为总体最优
  2. 结果发现这总单单的将两个最优解和是无法求到最优的解,在leetcode里看他人的解题思路,发现需要将求一条路最大值的动态规划解题思路转变,转变为同时求两条路最大和的动态规划过程:
    dpk[x1][x2]:k[0,0][x1, kx1][x2, kx2]dpk[x1][x2]=max(dpk1[x1][x2], dpk1[x11][x2], dpk1[x1][x21], dpk1[x11][x21])
  3. 这个过程很抽象,特别是dpk[x1][x2]的含义,有点难以理解,可能需要画图进行进一步的理解;总之算法实现时实际使用的是dp[x1][x2],k是多次循环覆盖的过程
  4. 多看看下面这段三层循环的代码理解,核心表示的就是上面状态转移方程的含义,每个k循环中的dp的含义代表了dpk,然后是用当前更新的dpk覆盖前一个循环的dpk1的值:
for (int k = 0; k <= maxLen; k++) {            int maxt = min(k, n-1);            for (int x1 = maxt; x1 >= 0; x1--)                for (int x2 = maxt; x2 >= 0; x2--) {                    int y1 = k - x1;                    int y2 = k - x2;                    if (y1 > n || y2 > n) continue;                    if (grid[x1][y1] < 0 || grid[x2][y2] < 0) {                        dp[x1][x2] = -1;                        continue;                    }                    int cherry = grid[x1][y1] + grid[x2][y2];                    if (x1-1 >= 0) dp[x1][x2] = max(dp[x1][x2], dp[x1-1][x2]);                    if (x2-1 >= 0) dp[x1][x2] = max(dp[x1][x2], dp[x1][x2-1]);                    if (x1-1 >= 0 && x2-1 >= 0) dp[x1][x2] = max(dp[x1][x2], dp[x1-1][x2-1]);                    if (dp[x1][x2] == -1) continue;                    if (x1 != x2) dp[x1][x2] += cherry;                    else dp[x1][x2] += grid[x1][y1];                }        }


  1. 这里就不贴详细代码了,具体可以看下面我的这个代码连接:

传送门:https://github.com/zhanzongyuan/leetcode/blob/master/741_Cherry%20Pickup.cpp

原创粉丝点击