uva 12222 Mountain Road

题意:

有一个单行道,两个方向都有车在等待。给出每个车的方向以及到达的时间以及走完这段路所需要的时间。

为了防止车祸,同向两车通过任一点的时间间隔不得小于10s。

求最后一辆车离开时刻的最小值。

思路:

这题最坑的就是,车可以降低速度。provided it is not slowed down by other cars in front。

分析一下样例2,

 
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 */

 

posted @ 2018-05-02 21:34  qrfkickit  阅读(419)  评论(0编辑  收藏  举报