http://acm.hdu.edu.cn/showproblem.php?pid=1024
The meaning of problems: there is a sequence containing a number of n, m subsequences find the subsequences which m and maximum. N-X ≤ ≤ ≤. 1 1, 000,000, S -32768 ≤ X ≤ 32767
Analysis: first with DP state [i] [j] denotes the front i j maximum number of extracted segment obtained. You may know, for the next number, the following three actions:
1, do not take this number.
2, take this number as the previous paragraph and tail.
3, take this number and as a new section of the head.
For these three operations, the state transition equation is:
dp[ i ][ j ]=max ( dp[ i ][ j-1 ] , dp[ i ][ j-1 ]+num[ j ] , max( dp[ i-1 ][ t ] ) + num[ j ] ) (1 < k < j)
Next, this range of n is 1e6, and the time of this algorithm, the spatial complexity will not therefore need to be optimized. (Wherein a selected operation can not be regarded as state of the selected record are then each time the j-th ANS)
①: Why do you want to optimize it?
We look Data range: 0 <m <= n < 1000000
For the above approach, we first need to run i: 1-> m represents 1 ~ m is divided into segments, and then run j: 0-> n i denotes the j-th number into segments, followed by run t: i-1-> n Looking max (dp [i-1] [t]),
It can be considered approximate time complexity is: O (m * n ^ 2), affirmative timeout. The opening of a two-dimensional spatial complexity certainly burst.
② how to optimize it?
Time: We found that for max (dp [i-1] [t]), we actually long as the preceding process to the maximum recorded in an array pre [t], then it can not run again cycles can be directly use.
Space: Because the final transient state are made progressively converted from a small, but transient start is the smallest, so for dp [i] [j] we can optimize a one-dimensional array dp [j ],
Because we run for (i: 1-> m) when starting from 1 run, when went 2 dp [J] is the data in the data dp [1] [J] is, we can use directly.
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int INF=0x3f3f3f3f; const int maxn=1000009; int a[maxn],dp[maxn],pre[maxn]; // DP [I] [J] = max (DP [I] [J-. 1] + A [J], DP [. 1-I] [K] + A [J]). 1-I <= K <= j-1 on the space, not the two-dimensional, time, m * i * i, not int main () { // solution, rolling the array plus an array + int n-, m, ANS; the while (Scanf ( " % % D D " , & m, & n-) =! the EOF) { for ( int I = . 1 ; I <= n-; I ++ ) { scanf("%d",a+i); } memset(dp,0,sizeof(dp)); memset(pre,0,sizeof(pre)); for(int i=1;i<=m;i++){ ANS = - INF; for ( int J = I; J <= n-; J ++) { // This is j = i! ! I into the number of mean i is a front segment DP [J] = max (DP [J- . 1 ] + A [J], pre [J- . 1 ] + A [J]); pre [J - . 1 ] = ANS; // here deliberately reverse scrolling the array in order to achieve ANS = max (ANS, DP [J]); // maximum-value storage // here there is also a reverse (because j-1 ) } } printf("%d\n",ans); } return 0; }