HDU1024 Max Sum Plus Plus[DP]

Max Sum Plus Plus

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 42745    Accepted Submission(s): 15453


Problem Description
Now I think you have got an AC in Ignatius.L's "Max Sum" problem. To be a brave ACMer, we always challenge ourselves to more difficult problems. Now you are faced with a more difficult problem.

Given a consecutive number sequence S1, S2, S3, S4 ... Sx, ... Sn (1 ≤ x ≤ n ≤ 1,000,000, -32768 ≤ Sx ≤ 32767). We define a function sum(i, j) = Si + ... + Sj (1 ≤ i ≤ j ≤ n).

Now given an integer m (m > 0), your task is to find m pairs of i and j which make sum(i1, j1) + sum(i2, j2) + sum(i3, j3) + ... + sum(im, jm) maximal (ix ≤ iy ≤ jx or ix ≤ jy ≤ jx is not allowed).

But I`m lazy, I don't want to write a special-judge module, so you don't have to output m pairs of i and j, just output the maximal summation of sum(ix, jx)(1 ≤ x ≤ m) instead. ^_^
 

 

Input
Each test case will begin with two integers m and n, followed by n integers S1, S2, S3 ... Sn.
Process to the end of file.
 

 

Output
Output the maximal summation described above in one line.
 

 

Sample Input
1 3 1 2 3 2 6 -1 4 -2 3 -2 3
 

 

Sample Output
6 8
Hint
Huge input, scanf and dynamic programming is recommended.

 

Resolution:

Meaning of the questions:

Do not overlap in the dividing number n of successive m subsections, sub-segments and so that the maximum.


 

DP [i] [j] indicates the j when the selection number, and dividing the maximum number of group i.

Then for any a j, we have two decisions:

  1. It with the previously divided and combined.
  2. Its own independence as a new set.

We can write the state transition equation:

dp[i][j]=max(dp[i][j-1]+a[j],dp[i-1][k]+a[j]),其中i-1<k<=n

The first decision dp [i] [j-1] + a [j] corresponds to a decision, the second decision dp [i-1] [k] + a [j] corresponding to the decision 2.

So why is the value of k i-1 <k <= n it?

First, we must be clear, when the division of the i-th group, i-1 groups before at least i-1 number, if this time k and then take the value of i-1 or before, it is certainly not true, after all, you can not draw out of 10 non-overlapping range in which the number 5.

But doing so will not only MLE, will TLE.

 

We must consider optimization.

The first is the rolling array, because we noticed dp array of current state and only about a state before, without the need to consider updating the status of all before, so we added a scroll.

But it is not only optimizes space.

 

Then we have to consider dealing with this k.

We must be clear meaning k: When partitioning group i, we need to divide the state of the group i-1 to find the optimal state transfer. That we might transfer process in every good record on the current stage of optimal state for the next stage you can choose between when selecting the optimal state k, instead of having to scan it again at this stage i-1.

So we can consider engage in an array pre [i] i-th divided the optimal solution when the group recorded it.

However, if the array allows pre [j] represents the optimum solution when the number of the j-th selected prior stage, can be optimized more, because it allows reuse pre array, DP may further be compressed into one-dimensional.

So every time we choose the j number when you update about the pre [j-1], the largest and save up does not include the j-1. Note that after each state to update the current maximum transfer and pre array!

Finally we get the state transition equation:

dp[j]=max(dp[j-1]+a[j],pre[j-1]+a[j]);

Reference Code:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<ctime>
 6 #include<cstdlib>
 7 #include<algorithm>
 8 #include<queue>
 9 #include<set>
10 #include<map>
11 #define INF 0x3f3f3f3f
12 const int N=1000010;
13 using namespace std;
14 int a[N],dp[N],pre[N];
15 int main()
16 {
17     int n,m;
18     while(scanf("%d%d",&m,&n)!=EOF)
19     {
20         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
21         memset(dp,0,sizeof(dp));
22         memset(pre,0,sizeof(pre));
23         dp[0]=-INF;
24         int ans;
25         for(int i=1;i<=m;i++){
26             ans=-INF;
27             for(int j=i;j<=n;j++){
28                  dp[j]=max(dp[j-1]+a[j],pre[j-1]+a[j]);
29                  pre[j-1]=ans;
30                  ans=max(ans,dp[j]);
31              }
32         }
33         cout<<ans<<endl;
34     }
35     return 0;
36 }

 

Guess you like

Origin www.cnblogs.com/DarkValkyrie/p/11105771.html