您的位置:首页 > 其它

poj 1976 A Mini Locomotive(01背包)

2017-08-11 00:24 513 查看
给你n个数,表示n个车厢拉的人数,给你三个小火车头,每个火车头可以拉连续的k节车厢,问这三个小火车头最多可以拉走多少人

dp[i][j]表示前i个火车头从前j节车厢最多可以拉多少人

dp[i][j]=max(dp[i-1][j-k]+preSum[j]-preSum[j-k],dp[i][j-1])

preSum表示前缀和,preSum[j]-preSum[j-k]表示从j开始往前k个车厢的总人数。

递推的过程和01背包很像的。K个车厢看成一个物品,当前dp[i][j]就是j往前连续k节车厢的人数总和 + 前i-1个车头在1-(j-k)这些车厢里(连续k个车厢)能拉走的最大人数 和 前i个车头在j-1个车厢里能拉走的最大人数 中的较大者

#include <stdio.h>
#include <string.h>
#define max(a,b) (a)>(b)?(a):(b)
const int MAXN = 50010;
int num[MAXN];
int preSum[MAXN];
int dp[5][MAXN*100];
int n,k;

void solve()
{
for(int i = 1; i <= 3; ++i)
{
for(int j = k; j <= n; ++j)
{
dp[i][j] = max(dp[i-1][j-k]+preSum[j]-preSum[j-k],dp[i][j-1]);
}
}
}

int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i = 1; i <= n; ++i)
{
scanf("%d",&num[i]);
preSum[i] = preSum[i-1]+num[i];
}
scanf("%d",&k);
solve();
printf("%d\n",dp[3]
);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: