Source of the topic: http://www.fjutacm.com/Problem.jsp?pid=1375 (Source: http://acm.hdu.edu.cn/showproblem.php?pid=1024)
Question meaning: In a sequence of length n, the maximum sum of m segments of uncorrelated intervals
Idea: We must first determine one thing, which is the state. Here I use dp[i][j] to represent the maximum sum of the first j numbers in i segments when a[j] is taken;
So in order to find the rules, we can first send Excel, take the sample as an example:
Then we can find that the 8 in the red circle is actually the state dp[2][6] (i=2, j=6), then we can think about how to derive this position, obviously, he can choose and divide i-1 The maximum value of the blocks is added, and the obtained i block may be the largest, or it can also be directly added to the position of j-1 of the same i block, which is equivalent to not disconnecting and obtaining the largest. Then he has only two choices, the first is dp[i][j-1], and the second is max(dp[i-1][i-1]~dp[i-1][j- 1]), that is, dp[i][i~n] is only related to the state of the line dp[i-1][i-1~n], and has nothing to do with others. Then we can save it in a rolling array; but if you use for to find max(dp[i-1][i-1]~dp[i-1][j-1]), then Cool, because then the complexity is O(n^3), that is, we use a maxn to remember the previous maximum value, and then update the record every time; see the code for details.
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 const int N= 1001000; 6 const long long INF=0x3f3f3f3f3f3f3f3f; 7 long long dp[2][N], maxn; 8 int a[N]; 9 int main( ){ 10 int m, n, t; 11 while(~scanf("%d%d", &m, &n)){ 12 t= 1 ; /// used to roll the array 13 for ( int i= 1 ; i<=n; ++ i) 14 dp[ 0 ][i]=- INF; 15 for ( int i = 1 ; i<=n; ++ i) 16 scanf( " %d " , &a [i]); 17 for ( int i= 1 ; i<=m; ++i, t= 1 -t){ /// t=1-t is rolling 18 dp[t][i]=dp[ 1-t][i- 1 ]+a[i]; /// The value of the diagonal is actually the sum of the first n items! ! 19 maxn=dp[ 1 -t][i- 1 ]; /// do n't forget this 20 for ( int j=i+ 1 ; j<=n; ++ j){ 21 maxn=max(maxn, dp [ 1 -t][j- 1 ]); /// maxn update record max(dp[i-1][i-1]~dp[i-1][j-1]) 22 dp[t][ j]=max(dp[t][j- 1 ], maxn)+a[j]; /// State transition step 23 } 24 } 25 t= 1-t; /// The influence of the last i>m ++i, t=1-t should be turned around 26 maxn=- INF; 27 /* * 28 Note that dp[i][j] means The first j numbers are the maximum sum of i segments in the case of taking a[j]; 29 is dp[m%2][n is not necessarily the optimal solution, because it may be larger without adding a[n]; 30 * */ 31 for ( int i=m; i<=n; ++ i) 32 maxn= max(maxn, dp[t][i]); 33 printf( " %I64d\n " , maxn); 34 } 35 return 0 ; 36 }