转移方程
d[i+1] [j] = s[j+m-1] - s[j-1] + max ( d[i] [x]), (1<=x<=j-m)
d[i] [j] 表示第i个区间以第j个数开始的最大值。
另外后面求最大值有个优化方法,因为每一次j总增加1,也就是x只增加1个值,所以只需把当前的和最大值比较就可以了。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include<map>
#define pi acos(-1.0)
#define eps 1e-6
#define inf 1<<30
#define INF 1ll<<60
#define ll long long
#define MOD 1000000007
using namespace std;
int a[5010];
ll d[5010][5010];
ll s[5010];
int main()
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
s[0]=0;
s[1]=a[1];
for(int i=2; i<=n; i++)
s[i]=s[i-1]+a[i];
for(int i=1; i+m-1+(k-1)*m<=n; i++)
d[1][i]=s[i+m-1]-s[i-1];
for(int i=1; i<=k-1; i++)
{
ll Max=0;
for(int j=1; j<=n; j++)
{
// for(int p=1; p+m<=j; p++)
// {
// Max=max(Max,d[i][p]);
// }
if(j-m>=1) //优化方法
Max=max(Max,d[i][j-m]);
else
Max=0;
d[i+1][j]=Max+s[j+m-1]-s[j-1];
}
}
ll ans=0;
for(int i=1; i<=n; i++)
ans=max(ans,d[k][i]);
printf("%I64d\n",ans);
return 0;
}