uva 12222 Mountain Road
题意:
有一个单行道,两个方向都有车在等待。给出每个车的方向以及到达的时间以及走完这段路所需要的时间。
为了防止车祸,同向两车通过任一点的时间间隔不得小于10s。
求最后一辆车离开时刻的最小值。
思路:
这题最坑的就是,车可以降低速度。provided it is not slowed down by other cars in front。
分析一下样例2,
4
A 0 100
B 50 100
A 100 1
A 170 100
首先B走,到达时间为150s,之后A1走,到达时间为250s,然后在160s的时候,A2可以出发,可以降低到和A1一直相隔10s的速度,到达时间为260s,也比A1晚10s。
之后A3在170s出发,270s到达,所以花费的总时间是270s。
不难想到的是,整个过程是A先走若干个 -> B走若干个 -> A走若干个。。。。。知道走完。
所以设dp[i][j][0/1]表示走了i辆A,j辆B且A是最后一辆(0),B是最后一辆(1)所花费的最少时间。
根据上面的过程,在dp[i][j][0]的时候,就可以枚举B走了K辆;
在dp[i][j][1]的时候,枚举A走了K辆。
由于同向的车每次相隔必须大于等于10s,所以设前一辆同向的车的出发时间为x,到达时间为y,本辆车实际到达的时间为a,那么出发时间就是b = max(a,x + 10),到达时间就是max(b,y + 10)。
时间复杂度为n^3。数据应该略水。。。。
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 using namespace std; 5 typedef long long ll; 6 const int N = 205; 7 ll dp[N][N][2]; 8 struct node 9 { 10 ll arr,cost; 11 node(){}; 12 node(int x,int y):arr(x),cost(y){}; 13 }a[N],b[N]; 14 int main() 15 { 16 int t; 17 scanf("%d",&t); 18 while (t--) 19 { 20 int orz; 21 int n = 0,m = 0; 22 scanf("%d",&orz); 23 for (int i = 0;i < orz;i++) 24 { 25 char s[10]; 26 int x,y; 27 scanf("%s%d%d",s,&x,&y); 28 if (s[0] == 'A') a[++n] = node(x,y); 29 else b[++m] = node(x,y); 30 } 31 for (int i = 0;i <= n;i++) 32 { 33 for (int j = 0;j <= m;j++) dp[i][j][0] = dp[i][j][1] = 1e16; 34 } 35 dp[0][0][1] = dp[0][0][0] = 0; 36 for (int i = 0;i <= n;i++) 37 { 38 for (int j = 0;j <= m;j++) 39 { 40 ll t1 = dp[i][j][0],t2 = 0; 41 for (int k = j + 1;k <= m;k++) 42 { 43 t1 = max(t1,b[k].arr); 44 t2 = max(t2,t1 + b[k].cost); 45 dp[i][k][1] = min(dp[i][k][1],t2); 46 t1 += 10; 47 t2 += 10; 48 } 49 t1 = dp[i][j][1],t2 = 0; 50 for (int k = i + 1;k <= n;k++) 51 { 52 t1 = max(t1,a[k].arr); 53 t2 = max(t2,t1 + a[k].cost); 54 dp[k][j][0] = min(dp[k][j][0],t2); 55 t1 += 10; 56 t2 += 10; 57 } 58 } 59 } 60 printf("%lld\n",min(dp[n][m][1],dp[n][m][0])); 61 } 62 return 0; 63 } 64 /* 65 2 66 4 67 A 0 60 68 B 19 10 69 B 80 20 70 A 85 100 71 4 72 A 0 100 73 B 50 100 74 A 100 1 75 A 170 100 76 */
康复训练中~欢迎交流!