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个车厢里能拉走的最大人数 中的较大者
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; }
相关文章推荐
- poj 1976 A Mini Locomotive(01背包)
- poj 1976 A Mini Locomotive(01背包)
- poj 1976 A Mini Locomotive 01背包
- POJ 1976 A Mini Locomotive(背包)
- POJ 1976 A Mini Locomotive【DP】
- poj-1976 A Mini Locomotive(DP,记忆化搜索)
- poj 1976 A Mini Locomotive 动规
- POJ 1976 A Mini Locomotive DP
- M - A Mini Locomotive POJ - 1976
- POJ 1976 A Mini Locomotive DP
- POJ 1976 A Mini Locomotive (动态规划)
- POJ_1976 A Mini Locomotive (dp)
- poj 1976 A Mini Locomotive(0/1背包)
- poj 1976 A Mini Locomotive 有依赖的背包问题
- POJ - 1976 A Mini Locomotive(背包DP)
- A Mini Locomotive POJ - 1976
- POJ 1976 A Mini Locomotive (DP 最大连续m子段和)
- POJ 1976 A Mini Locomotive (DP 最大连续m子段和)
- poj 1976 A Mini Locomotive (DP)
- poj 1976 A Mini Locomotive_简单dp