741. Cherry Pickup

来源:互联网 发布:高一历史优化学案答案 编辑:程序博客网 时间:2024/06/03 14:32

In a N x N grid representing a field of cherries, each cell is one of three possible integers.

  • 0 means the cell is empty, so you can pass through;
  • 1 means the cell contains a cherry, that you can pick up and pass through;
  • -1 means the cell contains a thorn that blocks your way.

    Your task is to collect maximum number of cherries possible by following the rules below:

  • Starting at the position (0, 0) and reaching (N-1, N-1) by moving right or down through valid path cells (cells with value 0 or 1);
  • After reaching (N-1, N-1), returning to (0, 0) by moving left or up through valid path cells;
  • When passing through a path cell containing a cherry, you pick it up and the cell becomes an empty cell (0);
  • If there is no valid path between (0, 0) and (N-1, N-1), then no cherries can be collected.

    Example 1:

    Input: grid =[[0, 1, -1], [1, 0, -1], [1, 1,  1]]Output: 5Explanation: The player started at (0, 0) and went down, down, right right to reach (2, 2).4 cherries were picked up during this single trip, and the matrix becomes [[0,1,-1],[0,0,-1],[0,0,0]].Then, the player went left, up, up, left to return home, picking up one more cherry.The total number of cherries picked up is 5, and this is the maximum possible.

    Note:

  • grid is an N by N 2D array, with 1 <= N <= 50.
  • Each grid[i][j] is an integer in the set {-1, 0, 1}.
  • It is guaranteed that grid[0][0] and grid[N-1][N-1] are not -1.

    想法是2遍DP,第一遍完了确认最偏左的path,把path上的grid数组设为0,在做一遍DP

    但是WA

    class Solution:    '''dp 2 times'''    def cherryPickup(self, a):        """        :type grid: List[List[int]]        :rtype: int        """        n = len(a)                def get():            dp = [[-1 for t in range(n)] for tt in range(n)]            dp[0][0]=1 if a[0][0]==1 else 0            for i in range(1,n):                if a[i][0]==-1:  break                dp[i][0] = dp[i-1][0]+a[i][0]            for i in range(1,n):                if a[0][i]==-1:  break                dp[0][i] = dp[0][i-1]+a[0][i]                            for i in range(1,n):                for j in range(1,n):                    if a[i][j]==-1:  continue                    if a[i-1][j]!=-1 :                        dp[i][j] = max(dp[i][j], dp[i-1][j]+a[i][j])                    if a[i][j-1]!=-1 :                        dp[i][j] = max(dp[i][j], dp[i][j-1]+a[i][j])            return dp                dp = get()        first = dp[n-1][n-1] if dp[n-1][n-1]>=0 else 0        if not first: return 0                '''        set visited path to left as most as possible        '''        visited = []        i, j = n-1, n-1        while True:            if i==0 and j==0: break            if i==0:                while j!=0:                    visited.append([i,j])                    j -= 1                break            if j==0:                while i!=0:                    visited.append([i,j])                    i -= 1                break                        if dp[i][j]==dp[i][j-1]+a[i][j]:                j -= 1            else:                i -= 1            visited.append([i,j])        a[n-1][n-1],a[0][0]=0,0        for i,j in visited:            a[i][j] = 0                dp = get()        second = dp[n-1][n-1] if dp[n-1][n-1]>=0 else 0        return first+second    s = Solution()print(s.cherryPickup([[1,1,-1],[1,-1,1],[-1,1,1]]))print(s.cherryPickup([[0,1,-1],[1,0,-1],[1,1,1]]))


    It is the same as two path start from (0, 0) to (n-1, n-1)
    dp[x1][x2] means two length p path , currently one arrived at [..., x1] , the other is at [..., x2], the max value we can get

    loop on length p, update max.


  • class Solution:    def cherryPickup(self, grid):        """        :type grid: List[List[int]]        :rtype: int        """        n, path_len = len(grid), 2*len(grid)-1        dp1 = [[-1 for t in range(n)] for tt in range(n)]         dp2 = [[-1 for t in range(n)] for tt in range(n)]        dp1[0][0], dp2[0][0] = grid[0][0], grid[0][0]                # p is the length of the path        for p in  range(2, 1+path_len):            for x1 in range(n):                for x2 in range(x1, n):                                        y1, y2 = p-1-x1, p-1-x2                    if y1<0 or y2<0 or y1>=n or y2>=n:continue                    if grid[y1][x1]<0 or grid[y2][x2]<0:                        dp2[x1][x2] = -1                        continue                                        best, delta = -1, grid[y1][x1]                    if x1!=x2:  delta += grid[y2][x2]                                        # two path from left , left                    if x1>0 and x2>0 and dp1[x1-1][x2-1]>=0:                        best = max(best, dp1[x1-1][x2-1]+delta)                    # two path from left , up                    if x1>0 and y2>0 and dp1[x1-1][x2]>=0:                        best = max(best, dp1[x1-1][x2]+delta)                    # two path from up , left                    if y1>0 and x2>0 and dp1[x1][x2-1]>=0:                        best = max(best, dp1[x1][x2-1]+delta)                    # two path from up , up                    if y1>0 and y2>0 and dp1[x1][x2]>=0:                        best = max(best, dp1[x1][x2]+delta)                                            dp2[x1][x2] = best            dp1, dp2 = dp2, dp1        return 0 if dp1[n-1][n-1]<0 else dp1[n-1][n-1]s = Solution()print(s.cherryPickup([[1,1,1,1,0,0,0],[0,0,0,1,0,0,0],[0,0,0,1,0,0,1],[1,0,0,1,0,0,0],[0,0,0,1,0,0,0],[0,0,0,1,0,0,0],[0,0,0,1,1,1,1]]))


  • 原创粉丝点击