Max Sum Plus Plus (Dynamic Programming) HDU1024

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 }
poor code

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325887852&siteId=291194637