标签:
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 2485 | Accepted: 1388 |
Description
Input
Output
Sample Input
1 7 35 40 50 10 30 45 60 2
Sample Output
240
题意:
有三个火车头,n个车厢,每个车厢里面对应的有一定的人数。规定每个火车头最多拉m个连续的车厢而且他们拉的车厢一定是从左到右连续的,问它能够拉的最多的人数;
思路:
类似01背包的解法,首先每个火车最多拉m个连续的车厢,这里我们把只要存在连续的m个车厢的就看成一个物品。相当于往背包容量为3的背包里面放物品所得的最大价值量。但是这里注意每连续的m个车厢为一个物品,f[i][j] = max(f[i - 1][j],f[i - m][j - 1] + sum[i] - sum[i - m]); 这里对于每个物品要么不放,要么就是放(放连续的m个车厢)
sum[i] = a[0] + a[1] + ... + a[i];
之前看到这个解题思路感觉一点有疑问:会不会有重复,第一节拉1,2;第二节拉2,3这样的,最后结论是不会;因为不取这个车厢的话,那必然就是【i-1】【j】,如果取的话那么肯定就是【i-m】【j-1】,跳到了i-m了,所以不会重,太弱了,其实这道题也挺简单,就是不会,弱
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 6 using namespace std; 7 const int MAX = 50000 + 10; 8 int dp[MAX][5],sum[MAX],a[MAX]; 9 int main() 10 { 11 int t,n,m; 12 scanf("%d", &t); 13 while(t--) 14 { 15 scanf("%d", &n); 16 memset(dp, 0, sizeof(dp)); 17 memset(sum, 0, sizeof(sum)); 18 for(int i = 1; i <= n; i++) 19 scanf("%d", &a[i]); 20 for(int i = 1; i <= n; i++) 21 sum[i] = sum[i - 1] + a[i]; 22 scanf("%d", &m); 23 int tp; 24 for(int i = 1; i <= n; i++) 25 { 26 for(int j = 1; j <= 3; j++) 27 { 28 if(i < m) //因为最多是m节,不足m也是可以的,需要处理一下 29 { 30 tp = 0; 31 } 32 else 33 tp = i - m; 34 dp[i][j] = max(dp[i - 1][j], dp[tp][j - 1] + sum[i] - sum[tp]); 35 } 36 } 37 printf("%d\n", dp[n][3]); 38 } 39 return 0; 40 }
POJ1976A Mini Locomotive(01背包装+连续线段长度)
标签:
原文地址:http://www.cnblogs.com/zhaopAC/p/5055229.html