EOJ:Mountain Road

Mountain Road

Time Limit: 10000MS Memory Limit: 65536K
Total Submits: 21 Accepted: 8

Description

In the Franconian Switzerland, there is a narrow mountain road. With only a single lane, this is a bottleneck for two-way traffic. Your job is to schedule incoming cars at both ends so that the last car leaves the road as early as possible. 

Each car is specified by three values: the direction in which it is going, the arrival time at the corresponding beginning of the road, and the driving time this car needs to get through, provided it is not slowed down by other cars in front. Cars cannot overtake each other on the mountain road, and reordering cars in the queues at the ends of the road is not allowed. 

For safety reasons, two successive cars going in the same direction may not pass any point of the road within less than 10 seconds. This ensures that the second car will not crash into the first car if the latter brakes hard. However, if another car passes in the other direction in between, it will be clear that the road is empty, so in this case, this rule does not apply.

 

Input

The first line of the input consists of a single integer c (1 ≤ c ≤ 200), the number of test cases. 

Then follow the test cases, each beginning with a single line consisting of an integer n (1 ≤ n ≤ 200), the number of cars you are to consider in this test case. The remainder of each test case consists of n lines, one line per car, starting with a single upper case letter (“A” or “B”), giving the direction in which the car is going. Then follow, on the same line, two integers t (0 ≤ t ≤ 100000) and d (1 ≤ d ≤ 100000), giving the arrival time at the beginning of the road and the minimum travel time, respectively, both in seconds. 

Within a test case, the cars are given in order of increasing arrival time, and no two cars will arrive at the same time.

 

Output

For each test case, print a single line consisting of the point in time (in seconds) the last car leaves the road when the cars are scheduled optimally.

 

Sample Input

2
4
A 0 60
B 19 10
B 80 20
A 85 100
4
A 0 100
B 50 100
A 100 1
A 170 100

 

Sample Output

200
270
http://202.120.106.94/onlinejudge/problemshow.php?pro_id=318
——————————————————————————————————————————————————————————————————
题目意思是说有一条路(单向) 左右各有有一些车要过这条路,对于每一边,你不能改变车的出发顺序。你只能改变某一时刻,先左边发车还是先右边发车。
dp[i][j][K]表示左边过了I辆,右边过了J辆,K=0表示最后一辆是左边开出的,K=1表示从右边开出。
由题目意思,如果两辆车同向,则后一辆车的出发时间为ST=MAX(自身出发时间,前一辆车出发时间+10),后一辆车的到达时间为MAX(前一辆车到达时间+10,ST)。

本来我想直接用dp[i][j][0]和dp[I][J][1]分别来更新DP[I+1][J][0]和DP[I][J+1][1],但是做了以后发现一个问题,如果有几辆车都是同向,当前车的出发时间没法确定。
因为当前车的出发时间跟前面一辆车有关,而前面一辆车的出发时间可能跟再前面一辆有关。
例如样例中:
A 0 100
B 50 100
A 100 1
A 170 100
假如我们不看第二辆车。那么第一辆车在100的时候到达,第三辆车最早在110的时候到达,但是第三辆车最早出发时间是10!!!从而第四辆车在20的时候就可以出发了。
如果按我的方法做,那么会认为第三辆车的出发时间是109!!这样第四辆车要219的时候才能到!

改进方法:
用dp[I][J][0]来更新DP[I][J+X][1],用DP[I][J][1]来更新DP[I+X][J][0],表示同一个方向连续开了X辆车。
1 #include<stdio.h>
2 #include<memory.h>
3  struct node
4 {
5 int t,d;
6 }l[205],r[205];
7  int dp[205][205][2];
8  int t,d,n,i,j,k,st,fin,oo,ans,runs,t1,t2;
9  char c;
10 int min(int a,int b)
11 {
12 return a>b?b:a;
13 }
14 int max(int a,int b)
15 {
16 return a<b?b:a;
17 }
18 void init()
19 {
20 scanf("%d", &n);
21 t1=t2=0;
22 for (i = 1; i <= n; i++)
23 {
24 getchar();
25 scanf("%c%d%d", &c, &t, &d);
26 if (c == 'A')
27 {
28 l[++t1].t = t;
29 l[t1].d = d;
30 }
31 else
32 {
33 r[++t2].t = t;
34 r[t2].d = d;
35 }
36 }
37 }
38 void work()
39 {
40 memset(dp,0x1f,sizeof(dp));
41 oo=dp[0][0][0];
42 dp[0][0][1]=dp[0][0][0]=0;
43 for (i=0;i<=t1;i++)
44 for (j=0;j<=t2;j++)
45 {
46 if (dp[i][j][0]<oo)
47 {
48 st=max(dp[i][j][0],r[j+1].t);
49 dp[i][j+1][1]=min(dp[i][j+1][1],st+r[j+1].d);
50 for (k=j+2;k<=t2;k++)
51 {
52 st=max(st+10,r[k].t);
53 fin=max(st+r[k].d,dp[i][k-1][1]+10);
54 dp[i][k][1]=min(dp[i][k][1],fin);
55 }
56 }
57 if (dp[i][j][1]<oo)
58 {
59 st=max(dp[i][j][1],l[i+1].t);
60 dp[i+1][j][0]=min(dp[i+1][j][0],st+l[i+1].d);
61 for (k=i+2;k<=t1;k++)
62 {
63 st=max(st+10,l[k].t);
64 fin=max(st+l[k].d,dp[k-1][j][0]+10);
65 dp[k][j][0]=min(dp[k][j][0],fin);
66 }
67 }
68 }
69 ans=min(dp[t1][t2][0],dp[t1][t2][1]);
70 printf("%d\n",ans);
71 }
72 int main()
73 {
74 scanf("%d",&runs);
75 while (runs--)
76 {
77 init();
78 work();
79 }
80 return 0;
81 }

posted on 2011-02-17 19:55  风也轻云也淡  阅读(206)  评论(0编辑  收藏  举报