Ahan Jianzhi offer Day 09 dynamic programming 2

catalogue

dynamic programming

Maximum sum of 1 continuous subarrays

1. Violence Act

two   Divide and conquer (official solution -- line segment tree)

3. Dynamic planning + temporary variables

4. Dynamic planning + in situ modification

2 maximum value of gifts

1. Dynamic programming + 2D array

2. Open one more row and one more column 0 optimization code

dynamic programming

Maximum sum of 1 continuous subarrays

Sword finger Offer 42. Maximum sum of continuous subarrayshttps://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/

1. Violence Act

Violence lawO(N2)O(1)

two   Divide and conquer (official solution -- line segment tree)

Divide and conquerO(NlogN)O(logN)

This divide and conquer method is similar to the pushUp operation of "solving the longest common ascending subsequence problem with line segment tree". Maybe the reader hasn't touched the segment tree yet. It doesn't matter. The content of method 2 assumes that you don't have any basis for the segment tree. Of course, if readers are interested, it is recommended to read the segment tree interval merging method to solve the "interval longest continuous rising sequence problem" and "interval maximum sub segment sum problem" asked many times, which is still very interesting.

First define an operation   get(a, l,r)   Represents a query   aa   sequence   The maximum sub segment sum in the [l,r] interval, then the final required answer is   get(nums, 0, nums.size() - 1). How to divide and conquer to achieve this operation?

For an interval   [l, R], let's take M = ⌊ (l+r)/2 ⌋, for the interval   [l,m]   and   [m+1,r]   Divide and conquer solution. When recursion goes deep layer by layer until the interval length is reduced to   one   Recursion "starts to pick up" when. Consider how to pass it at this time   [l,m]   Interval information and   The information of [M + 1, R] interval is combined into interval   [l,r][l,r]   Information about. The two most critical issues are:

  • What information do you want to maintain?
  • How do you combine this information?

For an interval   [l,r], we can maintain four quantities:

  • Sum   express   [l,r]   Inside   l   Is the maximum sub segment of the left endpoint and
  • rSum   express   [l,r]   Inside   rr is the maximum sub segment sum of the right endpoint
  • mSum   express   [l,r]   Maximum sub segment and
  • iSum   express   [l,r]   Interval sum of

hereinafter referred to as   [l,m]   by   [l,r]   Left subinterval of [m+1,r]   by   [l,r]   Right subinterval of. Consider how to maintain these quantities? (how to combine the information of the left and right subintervals to obtain   [l,r]   Information about the project)?

For length   one   Interval of   [i,i], the values of the four quantities are the same as nums[i]   equal. For lengths greater than   one   Interval of:

  • First of all, the best maintenance is   Isum, interval [l,r]   of   iSum   It's equal to the left subinterval   iSum   Add "right sub interval"   iSum.
  • about   There are two possibilities for the lSum of [l,r], which is either equal to the lSum of the "left subinterval"   lSum, or iSum equal to "left subinterval"   Add "right sub interval"   lSum, whichever is greater.
  • about   [l,r]   of   rSum, similarly, it is either equal to the value of the "right subinterval"   rSum, or iSum equal to "right subinterval"   Add rSum of "left sub interval", and the two are larger.
  • When the above three quantities are calculated, it is easy to calculate   [l,r]   mSum   Yes. We can consider   Msum of [l,r]   Whether the corresponding interval crosses   m——
    • May not cross   m. That is to say   [l,r]   mSum for   It may be the mSum of the "left sub interval"   And mSum of "right subinterval"   One of;
    • May also cross   m. It may be rSum of "left subinterval"   And lSum of "right subinterval"   Sum.
    • The last three are larger.

In this way, the problem has been solved.

class Solution {
    public class Status {
        public int lSum, rSum, mSum, iSum;

        public Status(int lSum, int rSum, int mSum, int iSum) {
            this.lSum = lSum;
            this.rSum = rSum;
            this.mSum = mSum;
            this.iSum = iSum;
        }
    }

    public int maxSubArray(int[] nums) {
        return getInfo(nums, 0, nums.length - 1).mSum;
    }

    public Status getInfo(int[] a, int l, int r) {
        if (l == r) {
            return new Status(a[l], a[l], a[l], a[l]);
        }
        int m = (l + r) >> 1;
        Status lSub = getInfo(a, l, m);
        Status rSub = getInfo(a, m + 1, r);
        return pushUp(lSub, rSub);
    }

    public Status pushUp(Status l, Status r) {
        int iSum = l.iSum + r.iSum;
        int lSum = Math.max(l.lSum, l.iSum + r.lSum);
        int rSum = Math.max(r.rSum, r.iSum + l.rSum);
        int mSum = Math.max(Math.max(l.mSum, r.mSum), l.rSum + r.lSum);
        return new Status(lSum, rSum, mSum, iSum);
    }
}

3. Dynamic planning + temporary variables

Dynamic programming analysis:

  • Status definition:   Set dynamic programming list   dp  , dp[i] represents the element num [i]   Is the maximum sum of contiguous subarrays at the end.

    • Why is the maximum sum defined   Element must be included in DP [i]   nums[i]: guarantee   dp[i]   Recursive to   Correctness of dp[i+1]; If not   nums[i], the recursion does not meet the requirements of the topic   Continuous subarray   requirement.
    • Let dp be a one-dimensional array, where the value of dp[i] represents the largest subarray and sum of the array composed of the first I numbers  .
  • Transfer equation:   If dp[i − 1] ≤ 0  , Description dp[i − 1]   Yes, dp[i]   Negative contribution, i.e. dp[i − 1]+nums[i]   Not as good as   nums[i] itself is large.
    • When dp[i − 1] > 0: execute dp[i]=dp[i − 1]+nums[i];

    • When dp[i − 1] ≤ 0: execute dp[i]=nums[i];  

  • Initial state: dp[0] = nums[i];, Namely   The maximum sum of consecutive subarrays ending in num [0] is num [0]  .
  • Return value: Return   dp   The maximum value in the list represents the global maximum value.

4. Dynamic planning + in situ modification

Reduced space complexity:

  • because   dp[i] only with   dp[i-1] and   nums[i]   So the original array can be   nums   be used as   dp   List, i.e. directly in   nums   You can modify it on the.
  • As omitted   dp   The list uses additional space, so the space complexity from   O(N)   lower   O(1)  .

Complexity analysis:

  • Time complexity   O(N)  :   Linear ergodic array   nums   To get results, use o (n)   Time.
  • Spatial complexity   O(1)  :   Use extra space of constant size.

2 maximum value of gifts

Sword finger Offer 47. Maximum value of gifthttps://leetcode-cn.com/problems/li-wu-de-zui-da-jie-zhi-lcof/

1. Dynamic programming + 2D array

package jzof.Day09;

/**
 * @author ahan
 * @create_time 2021-11-11-11:45 morning
 * There is a gift in each grid of an m*n chessboard, and each gift has a certain value (value greater than 0).
 * You can start from the upper left corner of the chessboard to take the gifts in the grid, and move one grid to the right or down at a time until you reach the lower right corner of the chessboard.
 * Given the value of a chessboard and the gifts on it, please calculate the maximum value of gifts you can get?
 */
public class _47 {
    public static void main(String[] args) {
        int [][] nums = new int[][]{
                {1,3,1},
                {1,5,1},
                {4,2,1}
        };
        System.out.println(new _47().maxValue(nums));
    }
    public int maxValue(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        int[][] dp = new int[m][n];
        dp[0][0] = grid[0][0];
        for (int i = 1; i < m; i++) {
            dp[i][0] = dp[i-1][0] + grid[i][0];
        }
        for (int i = 1; i < n; i++) {
            dp[0][i] = dp[0][i-1] + grid[0][i];
        }
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1])+grid[i][j];
            }
        }
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                System.out.print(dp[i][j]+"\t");
            }
            System.out.println("  ");
        }
        return dp[m-1][n-1];
    }
}

It's the same idea and method as the boss, hahaha ~ but the boss modified it in situ...

  Space efficiency is not much worse~

Complexity analysis:  

  • Time complexity O(MN)  :   M,N   Row height and column width of matrix respectively; Dynamic programming needs to traverse the whole grid   Matrix, using   O(MN) time.
  • Space complexity O(1)  :   In place modification uses additional space of constant size.

2. Open one more row and one more column 0 optimization code

public int maxValue(int[][] grid) {
        int row = grid.length;
        int column = grid[0].length;
        //dp[i][j] represents the maximum value from grid[0][0] to grid[i - 1][j - 1]
        int[][] dp = new int[row + 1][column + 1];
        for (int i = 1; i <= row; i++) {
            for (int j = 1; j <= column; j++) {
                dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
            }
        }
        return dp[row][column];
    }

Tags: Algorithm leetcode Dynamic Programming

Posted on Wed, 10 Nov 2021 23:20:55 -0500 by flyankur