dp百题进度条[1/100]

一列火车有一个火车头拖着一长串的车厢,每个车厢有若干个乘客。
一旦火车头出了故障,所有的车厢就只能停在铁轨上了,因此铁路局给每列火车配备了三个迷你火车头,每个迷你火车头可以拖动一定数量的车厢,以便火车头发生故障后能够拖走部分车厢。
  铁路部门对迷你火车头作了如下规定:
  1.迷你火车头能够拖动的最大车厢数是确定的,这个数量对三个迷你火车头都是相同的。
  2.一旦火车头发生故障,迷你火车头要拖走尽可能多的旅客,每节车厢的旅客数事先是已知的,并且旅客不得随意更换车厢。
  3.一个迷你火车头拖走的车厢必须是连续的,所有车厢从1开始编号。
  假如有7节车厢,一个迷你火车头最多可以拖动二节车厢,1到7号车厢中的旅客人数分别为35,40,50,10,30,45和60。
  如果三个迷你火车头拖走的车厢分别是1-2,3-4和6-7,它们带走的旅客总数将达到240人,其它任何方案都不可能超过该数,所以240就是这个问题的解。
  给定车厢数,每节车厢的旅客人数和一个迷你火车头能拖动的最大车厢数,写一个程序求出三个迷你火车头最多能带走的旅客数。

输入格式
输入文件共有三行。
第一行为一个正整数n,其中n<=50,000,表示车厢总数;
第二行为n个用空格隔开的整数,依次表示n节车厢的旅客人数,每节车厢人数不超过100;
第三行为一个正整数m表示迷你火车头能够拖动的最大车厢数,其中m<=n/3。

输出格式
输出文件仅有一行包含一个整数表示三个迷你火车头最多能带走的旅客数。
1
测试样例1
输入
7
35 40 50 10 30 45 60
2

输出
240

我们定义dp[i][j]为第i个火车头时,拖了前j个车厢的最大值
我们用front数组来存前缀
状态转移方程
dp[i][j] = max_(dp[i][j - 1],dp[i - 1][j - m] + front[j] - front[j - m]);

Code


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 50000 + 5;

int n,t,m;
int dp[5][MAXN],train[MAXN],front[MAXN];

int max_(int x,int y){
    if (x > y) return x;
    else return y;
}

int main(){
    scanf("%d",&t);

    while(t--){
        scanf("%d",&n);

        for (register int i = 1 ; i <= n ; i++) scanf("%d",&train[i]),front[i] = front[i - 1] + train[i];

        scanf("%d",&m);

        for (register int i = 1 ; i <= 3 ; i++){
            for (int j = m ; j <= n ; j++){
                dp[i][j] = dp[i][j - 1];
                dp[i][j] = max_(dp[i][j - 1],dp[i - 1][j - m] + front[j] - front[j - m]);
            }
        }

        printf("%d\n",dp[3][n]);
    }

    return 0;
}
12-17 05:02