Dynamic Programming - Minimize the sum of the maximum values in all subsequences

Problem Description

Given a length NNN -integer order( a 1 , a 2 , . . . , a N ) (a_1,a_2,...,a_N)(a1,a2,...,aN) , divide it into multiple subsequences (the subsequence in this problem is a continuous segment of integers), satisfying that the sum of integers in each subsequence is not greater than a numberBBB , design a partition method that minimizes the sum of the maximum values ​​in all subsequences. It shows that it has optimal substructure and overlapping subproblems.

For example: Integer sequence with sequence length 8 ( 2 , 2 , 2 , 8 , 1 , 8 , 2 , 1 ) (2,2,2,8,1,8,2,1)(2,2,2,8,1,8,2,1) B = 17 B=17 B=1 7 , which can be divided into three subsequences( 2 , 2 , 2 ) (2,2,2)(2,2,2) ( 8 , 1 , 8 ) (8,1,8) (8,1,8 ) and( 2 , 1 ) (2,1)(2,1 ) , then the sum of integers in each subsequence is not greater than 17, and the sum of the maximum values ​​in all subsequences is 12 as the final result.

Algorithm idea

This topic seems to be very convoluted and very complicated. It is required to find the sum of the maximum value in the smallest subsequence, and it is also required that the sum of integers in the subsequence is not greater than BBB. _ Because we know that we need to use the idea of ​​dynamic programming to solve it, and dynamic programming generally uses an array to store the results of the process. When the algorithm is executed, the last element of the array will be the answer we want. So we can use the array nums numsregardless of the specific stepsn u m s to indicate that the given length isNNThe integer sequence of N , the subscript starts from 1, set an arraysum [ i ] sum[i]s u m [ i ] to represent from the 1st number to theiithThe sum of the maximum value in the smallest subsequence of i numbers, obviously sum [ 0 ] = 0 sum[0]=0sum[0]=0 , then our final result is to requiresum [ N ] sum[N]sum [ N ] , the next step is to use the most basic example given in the title to start finding the law step by step .

  • N = 1 N=1 N=1 , there is only one element in the original sequence, thensum [ N ] = nums [ N ] = 2 sum[N]=nums[N]=2sum[N]=nums[N]=2
  • N = 2 N=2 N=2 , at this time there are two situations( 2 , 2 ) (2,2)(2,2) ( 2 ) , ( 2 ) (2),(2) (2),( 2 ) , thensum [ N ] = min ( 2 , 2 + 2 ) = 2 sum[N]=min(2,2+2)=2sum[N]=min(2,2+2)=2
  • N = 3 N=3 N=3 , at this time there are four situations( 2 , 2 , 2 ) (2,2,2)(2,2,2) ( 2 ) , ( 2 , 2 ) (2),(2,2) (2),(2,2) ( 2 , 2 ) , ( 2 ) (2,2),(2) (2,2),(2) ( 2 ) , ( 2 ) , ( 2 ) (2),(2),(2) (2),(2),( 2 ) , thensum [ N ] = min ( 2 , 2 + 2 , 2 + 2 , 2 + 2 + 2 ) = 2 sum[N]=min(2,2+2,2+2,2+ 2+2)=2sum[N]=min(2,2+2,2+2,2+2+2)=2

As can be seen from the above example, this question is actually a bit similar to the first question above, both of which are similar to having a cursor ppp walks through the entire sequence,ppThe position pointed to by p is cut in half, and the sequence is divided into two subsequences, just like the second case, the cursorppIf p is 0, the right side of the cursor is actually the whole array, and its maximum value is the maximum value of the array elements. WhenppWhen p reaches position 1, the array is divided into two parts, and the maximum value of the part in front of the cursor can besum[ 1 ] sum[1]s u m [ 1 ] is calculated, and the latter is the maximum value of the remaining elements. Obviously, only one element here is 2, and then the smallest of the two maximum values ​​is taken. Case 3 is also similar,ppp starts from 0 and goes all the way to 2, which is described in a formal language here as sum [ 3 ] = min ( sum [ 0 ] + max ( nums [ 1 ] , nums [ 2 ] , nums [ 3 ] ) , sum [ 1 ] + max ( nums [ 2 ] , nums [ 3 ] ) , sum [ 2 ] + max ( num [ 3 ] ) ) sum[3]=min(sum[0]+max(nums[1],nums [2],nums[3]), sum[1]+max(nums[2],nums[3]), sum[2]+max(num[3]))sum[3]=min(sum[0]+max(nums[1],n u m s [ 2 ] ,n u m s [ 3 ] ) ,sum[1]+max(nums[2],n u m s [ 3 ] ) ,sum[2]+m a x ( n u m [ 3 ] ) )
Since the cursor has been walking in[ 0 , i − 1 ] [0,i-1][0,i1 ] , so when we findsum[ i ] sum[i]s u m [ i ] , all the formulas are known, on this basis, we need to ensure that the sum of integers in each subsequence is not greater than 17, that is, max ( nums [ p + 1 ] , . . . , nums [ i ] ) ≤ B max(nums[p+1],...,nums[i])\leq Bmax(nums[p+1],...,nums[i])BSo
in the end we can get the transfer expression like this:
sum [ i ] = min ( sum [ p ] + max ( nums [ p + 1 ] , . . . , nums [ i ] ) ) , 0 ≤ p < i , ∑ k = p + 1 inums [ k ] ≤ B sum[i]=min(sum[p]+max(nums[p+1],...,nums[i])),0\leq p< i,\sum_{k=p+1}^{i}nums[k]\leq Bsum[i]=min(sum[p]+max(nums[p+1],...,nums[i])),0p<i,k=p+1inums[k]B

Description of the nature of the sub-questions

Generally speaking, if a topic can use dynamic programming algorithm, it should meet two conditions:

  • Optimal substructure: A problem is said to have an optimal substructure when the optimal solution to a problem includes the optimal solutions to subproblems.
  • Overlapping subproblems: During the solution of the problem, the solutions of many subproblems will be used multiple times.

With the recursive formula analyzed above, it is actually relatively easy to find that the problem has these two properties. Generally speaking, proof by contradiction is used to prove that it has an optimal substructure. Here is a brief proof:

Because sum [ i ] sum[i]s u m [ i ] issum [ p ] sum[p]s u m [ p ] transferred, ifsum [ i ] sum[i]s u m [ i ] is the optimal value, thensum [ p ] sum[p]s u m [ p ] must also be the optimal value. It can be proved by contradiction:
if there is
sum ′ [ p ] < sum [ p ] sum^{\prime}[p]<sum[p]sum[p]<sum[p]那么必定存在
s u m ′ [ i ] = m i n ( s u m ′ [ p ] + m a x ( n u m s [ p + 1 ] , . . . , n u m [ i ] ) ) < s u m [ i ] sum^{\prime}[i]=min(sum{\prime}[p]+max(nums[p+1],...,num[i]))<sum[i] sum[i]=min(sum[p]+max(nums[p+1],...,n u m [ i ] ) )<sum[i] s u m [ i ] sum[i] s u m [ i ] is not the optimal value, which contradicts the hypothesis. Therefore, the problem has the optimal substructure property.

The case of overlapping subproblems is also very easy to illustrate, ppp is a cursor, walking in[ 0 , i ) [0,i)[0,Between i ) , the sub-problems constitute the shape of the tree, and for each sub-problem of each layer of the tree, p will be in[ 1 , i ) [1,i)[1,i ) walk once, so there must be severalsum [ p ] sum[p]s u m [ p ] is a repeated subproblem, saysum [ 3 ] sum [3]s u m [ 3 ]sum [ 2 ] am[2]s u m [ 2 ] both containsum [ 1 ] sum [1]s u m [ 1 ] this subproblem.

Algorithm implementation

int split_subseq(b, n, nums[]) {
    
    
    sum(n + 1, INT_MAX);  // 存放从第1个数到第n个数的序列中的最小子序列中最大值的和
    sum[0] = 0;
    sum[1] = nums[1];  // 前两个值赋值

    for i from 2 to n:  // 自底向上求
        for p from 0 to i - 1:                    // 游标来回动
            int max_val = INT_MIN, add_sum = 0;
            for k from p + 1 to i:                // 找出来后面这个子序列的最大值
                add_sum += nums[k];  // 计算累加和
                max_val = max(max_val, nums[k]);  // 找出最大值
            end for;
            if add_sum < b:
		        // 状态转移方程
		        sum[i] = min(sum[i], sum[p] + max_val);
        end for;
    end for;
    return sum[n];
}

Guess you like

Origin blog.csdn.net/qq_41983842/article/details/123935462