Question Web site: http://acm.hdu.edu.cn/showproblem.php? PID = 1, 1024
Hdacm1024 Max sum plus: maximum sum of m non-Intersecting child segments:
Ideas:
DP [I] [J] indicates the optimal solution for dividing the first J elements into I segments. At the same time, this optimal solution ends with element a [J.
The transfer equation is DP [I] [J] = max {f [I] [J-1] + A [J], F [I-1] [k] + A [J], i-1 <= k <j)} (I <= j <= N-M + I)
Example: m = 2, n = 6, A = {-1 4-2 3-2 3 }:
Element in the figure. The above value indicates the largest sum of the current J elements divided into M segments. The following [] indicates the lower value of A, which is separated by commas. for example, if m = 2, a [5] =-2, the maximum sum is 5. The following [2], [] indicates that there are 2 child segments, the first sub-segment is a [2], and the second sub-segment is a [4, 5], that is, the largest and a [2] + (A [4] + A [5]) = 5.
When you evaluate the current value, you need to check its {left} and {max (from <top left> to <top left>)}. For example, if you want to evaluate DP [2] [4, look at DP [2] [3] and max {DP [1] [3], DP [1] [2], DP [1] [1]} on the left. the maximum value is the DP [1] [2] marked in red. another example is DP [2] [6] = max (DP [2] [5], max (DP [1] [5], DP [1] [4], DP [1] [3], DP [1] [2], DP [1] [1]), because DP [2] [5] = DP [1] [2] = 5 is the largest, there are two results, that is, [2, 6] or [2, 3, 4], [6].
Max (from <top left> to <top left>) can be represented by only one array pre [] to save space (scrolling array). Pre [] isThe maximum value from the first I segment to a [J-1], now [] is equivalent to DP [I] [J] and ends with a [J], including a [J].
The source code is as follows (reproduced ):
#include<iostream>
using namespace std;
#define MAXN 1000000
int num[MAXN+50],now[MAXN+50],pre[MAXN+50];
int main()
{
int m,n,i,j,k,ans,max_pre;
while(cin>>m>>n)
{
for(i=1;i<=n;i++)
{
Scanf("% D",&Num[I]);// Too many data items
To use scanf
}
memset(now,0,sizeof(now));
memset(pre,0,sizeof(pre));
ans=(-1)*(INT_MAX);
for(i=1;i<=m;i++)
{
max_pre=(-1)*(INT_MAX);
for(j=i;j<=n;j++)
{
now[j]=max(now[j-1]+num[j],pre[j-1]+num[j]);
pre[j-1]=max_pre;
if(now[j]>max_pre)
{
max_pre=now[j];
}//if
}//for j
}//for i
cout<<max_pre<<endl;
}//while
return 0;
} // Main