题意:
一个数列,n个数,找三个 m个连续数的子数列,使其和最大。
n比较大,三个子数列只能一个一个找了,
第一个 i=1~k dp(i,0)=max{dp(i-1,0),it[i]}; i代表第i个子数列选还是不选。
第二个 i=m+1~k dp(i,1)=max{dp(i-1,1),dp(i-m,0)+it[i]};
第三个 i=2m+1~k dp(i,2)=max{dp(i-1,2),dp(i-m,1)+it[i]};
#include<string.h>
#include<stdio.h>
int dp[50010][3],ai[50010],n,m;
int it[50010];
int max(int a,int b){
return a>b?a:b;
}
int main(){
int cas;
scanf("%d",&cas);
while(cas--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&ai[i]);
}
int it[50010],k=1;
scanf("%d",&m);
memset(it,0,sizeof(it));
for(int i=1;i<=n-m+1;i++){
for(int j=i;j<i+m;j++){
it[i]+=ai[j];
}
}
k=n-m+1;
memset(dp,0,sizeof(dp));
dp[0][0]=it[1];
for(int i=1;i<=k;i++){
dp[i][0]=max(dp[i-1][0],it[i]);
}
for(int i=m+1;i<=k;i++){
dp[i][1]=max(dp[i-1][1],dp[i-m][0]+it[i]);
}
for(int i=2*m+1;i<=k;i++){
dp[i][2]=max(dp[i-1][2],dp[i-m][1]+it[i]);
}
printf("%d\n",dp[k][2]);
}
return 0;
}