[741] leetcode cherry picking (dynamic programming)

Topic links: https://leetcode-cn.com/problems/cherry-pickup/

Title Description

An N x N grid (Grid) represents a cherry, each grid is represented by one of three numbers:

  • 0 indicates that the grid is empty, so you can pass through it.

  • 1 indicates that the grid filled with a cherry, then you can pick the cherries through it.

  • -1 indicates that the grid has thorns, blocking your way.

Your task is in compliance with the following rules, as far as possible to pick the most cherries:

  • Starting from the position (0, 0), and finally to (N-1, N-1), can only go down or right and can only be effective through the lattice (i.e., the lattice can only pass through the value 0 or 1, );
  • When reaching the (N-1, N-1) after you go to continue, until it returns to the (0, 0), can go up or to the left, and only through the effective lattice;
  • When you pass through the grid comprises a grid and a cherry, you pick the cherries and this grid becomes empty (the value becomes 0);
  • If (0, 0), and (N-1, N-1) may be a path does not exist between passes, then there is no pick to be a cherry.

Example 1:

输入: grid =
[[0, 1, -1],
 [1, 0, -1],
 [1, 1,  1]]
输出: 5
解释: 
玩家从(0,0)点出发,经过了向下走,向下走,向右走,向右走,到达了点(2, 2)。
在这趟单程中,总共摘到了4颗樱桃,矩阵变成了[[0,1,-1],[0,0,-1],[0,0,0]]。
接着,这名玩家向左走,向上走,向上走,向左走,返回了起始点,又摘到了1颗樱桃。
在旅程中,总共摘到了5颗樱桃,这是可以摘到的最大值了。

Description:

  • grid is a two-dimensional array of N * N, N is in the range of 1 <= N <= 50.
  • Each grid[i][j]is set in which a number of {-1, 0, 1}.
  • We can guarantee the start grid[0][0]and end grid[N-1][N-1]values will not be -1.

Thinking

Detailed topics English leetcode see the original post: https://leetcode.com/problems/cherry-pickup/discuss/109903/Step-by-step-guidance-of-the-O (N3) -time-and-O ( N2) -space-solution

Because the topics restricts grid[i][j]=1the access node only once, so the core of the problem is to avoid partI and partII repeat count.

I try violence

Violence back, exponential time complexity. Per roundtrip (4N-4)step, the possible number of round trips 2^(4N-4).

II dynamic programming attempt

(0, 0) ==> (N-1, N-1)And (N-1, N-1)==>(0,0)are using dynamic programming to get his son optimal solution, but overall (0, 0) ==> (N-1, N-1) ==> (0, 0)is not necessarily the optimal solution.

grid = [[1,1,1,0,1],
        [0,0,0,0,0],
        [0,0,0,0,0],
        [0,0,0,0,0],
        [1,0,1,1,1]].

In the above formula partI optimal solution can be obtained, (0, 0) ==> (0, 2) ==> (4, 2) ==> (4, 4)the sum of 6, partII most corresponding to the sum of 1, the overall sum of 7 back and forth. You may then be obtained all along the edge of the rectangle 8 cherry. So this greedy strategy may not be able to get the optimal solution.

III modified grid matrix of dynamic programming attempt

Record the current state of grid space complexity is too high

IV final version - does not modify the dynamic programming matrix grid

Can shorten the distance, you do not need to go to the bottom right corner? YES!

We redefined T(i,j)to simplify away (0, 0) ==> (i, j) ==> (0, 0)the maximum number available, without having to modify the input matrix. At this time, the original problem can be expressed as T(N-1,N-1). In order to obtain recurrence relations:

For each coordinate (i,j), we have two ways to reach and leave the point in two ways: (i-1, j)and (i, j-1), commute can be divided into the following four case:

Case 1: (0, 0) ==> (i-1, j) ==> (i, j) ==> (i-1, j) ==> (0, 0)
Case 2: (0, 0) ==> (i, j-1) ==> (i, j) ==> (i, j-1) ==> (0, 0)
Case 3: (0, 0) ==> (i-1, j) ==> (i, j) ==> (i, j-1) ==> (0, 0)
Case 4: (0, 0) ==> (i, j-1) ==> (i, j) ==> (i-1, j) ==> (0, 0)

By definition, case1 equivalent T(i-1, j) + grid[i][j], case2 equivalent T(i, j-1) + grid[i][j]. But our definition T(i, j)does not cover the last two scenarios: PartI last step and the first step PartII different. So we need to modify the T(i,j)definition, extended T(i, j, p, q), indicating that two paragraphs from (0, 0) ==> (i, j); (p, q) ==> (0, 0)the maximum number of cherry, without modifying the girdmatrix.

Similarly to the above, we have two ways arrival coordinates (i,j), the coordinates of two ways to leave(p,q)

Case 1: (0, 0) ==> (i-1, j) ==> (i, j); (p, q) ==> (p-1, q) ==> (0, 0)
Case 2: (0, 0) ==> (i-1, j) ==> (i, j); (p, q) ==> (p, q-1) ==> (0, 0)
Case 3: (0, 0) ==> (i, j-1) ==> (i, j); (p, q) ==> (p-1, q) ==> (0, 0)
Case 4: (0, 0) ==> (i, j-1) ==> (i, j); (p, q) ==> (p, q-1) ==> (0, 0)

By definition get:

Case 1 is equivalent to T(i-1, j, p-1, q) + grid[i][j] + grid[p][q];
Case 2 is equivalent to T(i-1, j, p, q-1) + grid[i][j] + grid[p][q];
Case 3 is equivalent to T(i, j-1, p-1, q) + grid[i][j] + grid[p][q];
Case 4 is equivalent to T(i, j-1, p, q-1) + grid[i][j] + grid[p][q];

Recurrence relations are:

T(i, j, p, q) = grid[i][j] + grid[p][q] + max{T(i-1, j, p-1, q), T(i-1, j, p, q-1), T(i, j-1, p-1, q), T(i, j-1, p, q-1)}

Constraints - avoid double-counting

At this point, we need to set constraints on the same grid to avoid a repeat count . As calculated above, we have T(i, j, p, q)counted the time gird[i][j]and gird[p][q], in order to avoid double counting, which should not be in two gird nodes T(i-1, j, p-1, q), T(i-1, j, p, q-1), T(i, j-1, p-1, q)and T(i, j-1, p, q-1)these four calculated is counted to any one of.

Obviously (i, j)not appear in (0, 0) ==> (i-1, j)or (0, 0) ==> (i, j-1), empathy (p, q)does not appear (p-1, q) ==> (0, 0)or (p, q-1) ==> (0, 0).

So if we can guarantee that (i, j)does not appear (p-1, q) ==> (0, 0)or (p, q-1) ==> (0, 0)and (p, q)do not appear (0, 0) ==> (i-1, j)or (0, 0) ==> (i, j-1), it will not happen repeat count. How to do it?

To (0, 0) ==> (i-1, j)and (0, 0) ==> (i, j-1)examples. We know that the boundaries of these paths, the former all rests on the rectangular path [0, 0, i-1, j], all of which rests on the rectangular path [0, 0, i, j-1], suggesting that the two paths together will fall rectangular [0, 0, i, j]in addition to the lower right corner (i,j)area. So if we guarantee (p, q)the rectangle [0, 0, i, j](except in exceptional circumstances beyond the (i,j)overlap), it will not appear in (0, 0) ==> (i-1, j)or (0, 0) ==> (i, j-1)on the path.

Similarly (i, j)must fall within a rectangular [0, 0, p, q]outside avoid double-counting. Summarize get one of the following three conditions should be to true :

  1. i < p && j > q
  2. i == p && j == q
  3. i > p && j < q

This shows that the commute T(i, j, p, q)is not value for all four coordinates are valid, and should satisfy the above conditions.

但是 T(i, j, p, q) 不满足self-consistency, For example, T(3, 1, 2, 3) is valid under these conditions but one of the terms in the recurrence relations, T(2, 1, 2, 2), would be invalid, and we have no idea how to get its value under current definition of T(i, j, p, q).

Self-consistent two-leg DP definition

So the above four parameters are interrelated, is not an independent parameter. Expression is not the simplest of the four parameters, we hope to find a subset of the above three conditions are satisfied in order to ensure a certain meet the above conditions. ** it can be observed: when i(p)increases, we must allow j (q) is reduced such that the above equation is satisfied, and vice versa ** (which is a negative association). So we can set i( p) and j( q) and is a constant n = i + j = p + q. (Note in the this Subset of Conditions, nCAN BE Interpreted AS at The Number The of Steps from at The Source position (0, 0). The I have have Also Tried OTHER Anti-Correlated Functions for iand jSUCH AS Their Product IS A Constant But IT DID not Work OUT. At The Recurrence Relations here Wallpaper play a role and constant sum turns out to be the simplest one that works.)

Thus the new conditions, we can rewrite satisfy n = i + j = p + qthe equation T(i, j, p, q)is:

T(n, i, p), where T(n, i, p) = T(i, n-i, p, n-p).

T(i-1, n-i, p-1, n-p) = T(n-1, i-1, p-1)
T(i-1, n-i, p, n-p-1) = T(n-1, i-1, p)
T(i, n-i-1, p-1, n-p) = T(n-1, i, p-1)
T(i, n-i-1, p, n-p-1) = T(n-1, i, p)

So get the recursive expression:

T(n, i, p) = grid[i][n-i] + grid[p][n-p] + max{T(n-1, i-1, p-1), T(n-1, i-1, p), T(n-1, i, p-1), T(n-1, i, p)}.

Of course, in the recurrence relation above, only one of grid[i][n-i] and grid[p][n-p] will be taken if i == p (i.e., when the two positions overlap). Also note that all four indices, i, j, p and q, are in the range [0, N), meaning n will be in the range [0, 2N-1) (remember it is the sum of i and j). Lastly we have the base case given by T(0, 0, 0) = grid[0][0].

The above equation, the time complexity: O (n- . 3), the spatial complexity: O (n- . 3); it was observed T(n, i, p)only with subproblems The depends Those ON n - 1, so the space can be reduced complexity of O (n ^ 2).

Code

/*
 * 动态规划
 * 时间复杂度O(n^3) 空间复杂度O(n^2)
 */

class Solution {
public:
    int cherryPickup(vector<vector<int>>& grid) {
        int N = grid.size(), M = (N<< 1) -1;    // M表示从(0,0)到(N-1,N-1)的格子数
        vector<vector<int>> dp(N, vector<int> (N,0));
        dp[0][0] = grid[0][0];

        for (int n = 1; n < M; ++n) {
            for (int i = N-1; i >= 0; --i) {
                for (int p = N-1; p >=0 ; --p) {
                    int j = n - i, q = n-p;
                    // 出界判断,出现障碍
                    if (j < 0 || j >= N || q < 0 || q >= N || grid[i][j] < 0 || grid[p][q] < 0) {
                        dp[i][p] = -1;
                        continue;
                    }

                    if(i>0) dp[i][p] = max(dp[i][p], dp[i-1][p]);
                    if (p > 0) dp[i][p] = max(dp[i][p], dp[i][p - 1]);
                    if (i > 0 && p > 0) dp[i][p] = max(dp[i][p], dp[i - 1][p - 1]);

                    if (dp[i][p] >= 0) dp[i][p] += grid[i][j] + (i != p ? grid[p][q] : 0);
                }
            }
        }

        return max(dp[N-1][N-1],0);
    }
};

Guess you like

Origin blog.csdn.net/zjwreal/article/details/92010190