//dp[i][j] 表示前i个数中有j段,得到的最大值
//dp[i][j] = max(dp[i-1][j] , dp[i-1][j-1]) + a[i]
//注意dp[i-1][j-1]为前i-1个点中不含i-1这个点得到的最优解
//dp[i-1][j]中必须要有i-1中这个点
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
const int maxn = 1000010 ;
const __int64 inf = 0x7fffffff;
typedef __int64 ll ;
ll dp[maxn][2] ;
int a[maxn] ;
int main()
{
int n , m ;
while(~scanf("%d %d" ,&m , &n))
{
memset(dp , 0 ,sizeof(dp)) ;
ll ans = -inf ;
for(int i = 1;i <= n;i++)
scanf("%d" ,&a[i]) ;
for(int j = 1;j <= m;j++)
{
ans = -inf ;
dp[j-1][(j)%2] = -inf;
for(int i = j;i <= n;i++)
{
dp[i][j%2] = max(dp[i-1][j%2] , dp[i-1][(j-1)%2]) + (ll)a[i] ;
dp[i][(j-1)%2] = max(dp[i][(j-1)%2] , dp[i-1][(j-1)%2]) ;
ans = max(ans , dp[i][j%2]) ;
}
}
printf("%I64d\n" ,ans) ;
}
}
hdu1024Max Sum Plus Plus dp
原文:http://blog.csdn.net/cq_pf/article/details/45675305