题目:http://poj.org/problem?id=1976
令dp(i, j)表示有i个火车头和j个车厢可以拉的最多人数,则对于最后一个车厢j进行分类讨论,则状态转移为
dp(i, j) = dp(i-1, j-M) + sum[j]-sum[j-M] //如果拉j
dp(i, j) = dp(i, j-1) //如果不拉j
#include <cstdio>
#include <algorithm>
using namespace std;
int N, M, sum[50005] = {0}, f[4][50005]= {0};
int main()
{
int test, i, j;
for(scanf("%d", &test); test--; ){
scanf("%d", &N);
for(i = 1; i <= N; ++i){
scanf("%d", &j);
sum[i] = sum[i-1] + j;
}
scanf("%d", &M);
for(i = 1; i < 4; ++i)
for(j = i * M; j <= N; ++j)//enumerate tail
f[i][j] = max(f[i][j-1], f[i-1][j-M] + sum[j]-sum[j-M]);
printf("%d\n", f[3][N]);
}
return 0;
}