hdu 2703
地址:http://acm.hdu.edu.cn/showproblem.php?pid=2703
题意:有n条通道首尾相连,每个通道有一个容量p和一个通过时间sec,表示最多一次能一起进p个人,需要sec的时间通过。现在有m个人在第一条通道的开始处,他们按照策略通过n条通道。策略有2点要遵守,1是每个通道同一时间只能进一组人,2是只要通道为空并且通道口有人,通道口的人必须立刻进入通道(显然这不一定是最佳策略)。
现在就按要求模拟题意,最后问m个人都通过的总用时。
mark:一开始觉得是个纯阅读题,再后来发现写起来有的地方也挺难想的。数据规模较小,直接暴搞(总用时最大才780s)。
代码:
1 # include <stdio.h> 2 # include <string.h> 3 4 5 int n ; 6 int dp[25][2010] ; 7 int p[25], sec[25] ; 8 9 10 int min(int a, int b){return a<b?a:b;} 11 int max(int a, int b){return a>b?a:b;} 12 13 14 int gao() 15 { 16 int ans = 0, t = 0 ; 17 int i, j ; 18 for (i = 0 ; i < n ; i++) 19 { 20 for (j = 0 ; ; j++) 21 { 22 if (j != 0) dp[i][j] += dp[i][j-1] ; 23 if (j > ans && dp[i][j] == 0) break ; 24 if (t != 0) t-- ; 25 else if (dp[i][j] != 0) 26 { 27 dp[i+1][j+sec[i]] += min(dp[i][j], p[i]) ; 28 dp[i][j] -= min(dp[i][j], p[i]) ; 29 t = sec[i]-1 ; 30 ans = max(ans, j+sec[i]) ; 31 } 32 } 33 } 34 return ans ; 35 } 36 37 38 int main () 39 { 40 int m, i ; 41 while (1) 42 { 43 scanf ("%d%d", &n, &m) ; 44 if (n == 0 && m == 0) break ; 45 n = -n ; 46 for (i = 0 ; i < n ; i++) 47 scanf ("%d%d", &p[i], &sec[i]) ; 48 49 memset (dp, 0, sizeof(dp)) ; 50 dp[0][0] = m ; 51 52 printf ("%d\n", gao()) ; 53 } 54 return 0 ; 55 }