Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 1024
Max sum plus
Time Limit: 2000/1000 MS (Java/others) memory limit: 65536/32768 K (Java/Others)
Total submission (s): 11256 accepted submission (s): 3701
Problem descriptionnow 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≤ JXOr IX≤ JY≤ JXIs 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. ^_^
Inputeach test case will begin with two integers m and n, followed by N integers s
1, S
2, S
3... S
N.
Process to the end of file.
Outputoutput the maximal summation described abve in one line.
Sample Input
1 3 1 2 32 6 -1 4 -2 3 -2 3
Sample output
68HintHuge input, scanf and dynamic programming is recommended.
Find the maximum M segment and in a sequence. The child segment length is arbitrary (cannot be 0 );
Because the data volume is a little large, we need to use a two-dimensional rolling array;
- But the test is mainly based on DP;
This is an upgraded version of the 1003 largest field and.
The root cause of DP is to break down a big problem into small problems and solve them one by one to reduce repeated computations.
To solve this problem, we need to find m non-overlapping fields in the series with a length of N. recursive process:
Sequence: A1, A2, a3...... an; has found the maximum M Segment and max1, but now I want
In A1, A2, A3,..., An, a (n + 1), find the maximum M Segment and max2. What is the relationship between max1 and max2?
We will discuss it in two cases. In max2WhetherContains an + 1;
Case 1: max2 does not include a (n + 1), that is, max2 = max1;
Case 2: max2 includes a (n + 1). Here we need to separate the two cases: whether max1 includes an (because the field is continuous)
2.1: max1 contains an, soMax2 = max1 + a (n + 1); (Directly lengthen the field containing)
2.2: max1 does not contain an, so a (n + 1) can onlyIndependent segmentsSo we need to find the sequence
Medium maximum M-1 segment and max3;Max2 = max3 + a (n + 1 );
From the above derivation, we can see that the maximum M Segment and (max2) of the sequence whose length is n + 1 are in the order of N.
The maximum M Segment of the column is related to the maximum M-1 segment of the sequence (max1) and the sequence (max3) with the length of N;
We use a two-dimensional array to represent this relationship.DP [I] [J]IndicatesFirst JMaximum ElementISegment and (whereYes
Include AJ---Last Element);
Because it must contain AJ, it can be expressed as: DP [I] [J] = max (Max (DP [I-1]
[K])+ A (J ),DP [I] [J-1]+ A (j ));
PS:DP [I] [J]Corresponding to the recursive processMax2;
Max (DP [I-1] [k])CorrespondingMax3;
DP [I] [J-1]CorrespondingMax1;
After completing the entire table, the maximum M Segment andMax (DP [m] [k]);
Code implementation:
# Include <stdio. h >__ int64 num [1000050] ;__ int64 DP [2] [1000050]; int main () {int I, j, k; int n, m; while (scanf ("% d", & M, & N )! = EOF) {__ int64 max =-99999; int sum = 0; for (I = 1; I <= N; I ++) {scanf ("% i64d ", & num [I]); DP [0] [I] = 0; DP [1] [I] = 0;} max =-99999; k = 1; // used as the scroll for (I = 1; I <= m; I ++) {max = DP [1-K] [I-1]; // This is the maximum value for recording DP [I-1] [J-1] DP [k] [I] = DP [1-K] [I-1] + num [I ]; // at this time, it is equivalent to DP [I] [I]; it is the sum of all elements; For (j = I + 1; j <= N; j ++) {If (DP [1-K] [J-1]> MAX) // This is the maximum value of recording DP [I-1] [J-1] Max = DP [1-K] [J-1]; DP [K ] [J] = DP [k] [J-1] + num [J]> MAX + num [J]? DP [k] [J-1] + num [J]: MAX + num [J];} k = 1-K;} max =-99999999; k = 1-K; for (I = m; I <= N; I ++) if (DP [k] [I]> MAX) max = DP [k] [I]; printf ("% i64d \ n", max );}} /* 1 3 1 2 32 6-1 4-2 3-2 32 5 4-1-2 4 12 6 4-1-2 4-1 1 */