分析:就是给你n个数,然后让你选k个区间,每个区间选m个数,问你所选的k个区间所有数的最大和是多少。
这显然是一道动态规划题目,设f[i][j]表示考虑到第i个数且已经选了j个区间的所有数的最大和。然后我们每次考虑是否要选取当前数,如果选的话那么当前数就是我们所选取的第j个区间的右端点,那么这个时候f[i][j]=f[i-m][j-1],因为我们要是选当前数作为第j个区间的右端点,那么第j-1个区间中的数就要从i-m个数及之前开始选了。如果我们不选当前数,那么f[i][j]=f[i-1][j],就是从前i-1个数中选j个区间。这样就完成了本道题目的更新。
下面是代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
const int N=5e3+10;
ll f[N][N],sum[N];//f[i][j]表示到达第i个位置选取j个区间的所选数的和的最大值
int main()
{
int n,m,k;
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
{
scanf("%lld",&sum[i]);
sum[i]+=sum[i-1];
}
f[m][1]+=sum[m];
for(int i=m+1;i<=n;i++)
for(int j=1;j<=min(k,i/m);j++)
f[i][j]=max(f[i-m][j-1]+sum[i]-sum[i-m],f[i-1][j]);
printf("%lld",f[n][k]);
return 0;
}