Advanced understanding of dynamic programming

In the past three days, I have done several dynamic programming problems. Unlike the past, these dynamic programming state transitions are not particularly easy to find. The use of recursion and timeouts is really a headache. Let me list the problems first.

First, let me talk about why we chose dynamic programming when we did this problem? In addition to the obvious problems (that is, dynamic programming), we usually find that some problems are very independent, without backwardness and forwardness, that is, our problems can be solved separately, such as this question, We are looking for sub-arrays. We added them in the front and separated them. We found that the values ​​of the back array have nothing to do with the front, so that we can consider using dynamic programming. We can also use recursion, although I keep timeout! ! ! (But memory ❀ can be added, I haven't memorized this question ~) After we found the method, we considered that each sub-array may be divided 1 to m times, without first considering whether the array divided by the sub-array will be Beyond m, we will find that the array behind us is determined by the number of divisions and the maximum value of the division in front of the array, which also means that we list an expression dp [i] [j] [k] (i is the position we reached, j is We loop to find the position of the smallest maximum value, k is the number of times) When we solve dp [i] [j] [m], we find that we do not need to list j, because we only need to get the smallest maximum value from 0 to i in the end Okay. Therefore, the equation is dp [i] [j] = Math.min (dp [i] [j], dp [j] [k-1] + i position to the total value of j position). Below we list the code:

    public int splitArray(int[] nums, int m) {
        int n = nums.length;
        int[][] f = new int[n + 1][m + 1];
        int[] sub = new int[n + 1];
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= m; j++) {
                f[i][j] = Integer.MAX_VALUE;
            }
        }
        for (int i = 0; i < n; i++) {
            sub[i + 1] = sub[i] + nums[i];
        }
        f[0][0] = 0;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                for (int k = 0; k < i; k++) {
                    f[i][j] = Math.min(f[i][j], Math.max(f[k][j - 1], sub[i] - sub[k]));
                }
            }
        }
        return f[n][m];        
    }

Just remember to deal with the critical issue.

The second question is also dizzy. I just wandered on the edge of it and couldn't find a breakthrough. This also reminded me that when we look for dynamic equations, it is not necessarily that our state at this time is related to the previous state. , May also form a state transition equation with any previous state, the following lists the topics:

Our problem state is to find the state at this time, but our last state is the state adjacent to this time, not the regular last state! So be careful! Below we list the code:

    public int videoStitching111(int[][] clips, int T) {
        int[] dp=new int[T+1];
        Arrays.fill(dp,T);
        dp[0]=0;
        for(int i=1;i<=T;i++){
            for(int[] clip:clips){
                if(i>=clip[0]&&i<=clip[1]){
                    dp[i]=Math.min(dp[i],dp[clip[0]]+1);
                }
            }
        }
        return dp[T]==T?-1:dp[T];
    }

 

Published 17 original articles · praised 0 · visits 141

Guess you like

Origin blog.csdn.net/qq_33286699/article/details/105656241