POJ

 POJ - 3846 Mountain Road

题意:n个人要过桥,有的人从左边来,有的人从右边来,给你他们到达桥一端的时间和过桥所需要的时间,要求相向而行的只能有一人,对于每一个点,不能在10s内有同向而行的人经过。

思路:f[i][j][A/B] 表示 从左边走了i个,从右边走了j个,最后一个是左边还是右边的最小时间。问你最后一辆车的到达时间最小是多少。

  对于每一个这样的状态,可以往后面一直推过了k辆反向的车所消耗的时间,只要把出发时间和到达时间的间距都压在10s以上就可以满足条件,不断的更新最优值就行了。

  我之前写的时候对于每一个状态只知道推相邻的状态,这样导致转移的代码特别冗杂,最终答案也没有对,而且还超时了,所以这题来讲还是很遗憾没写出来,想到了状态,只是转移的时候犯了错误,没能过掉。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #define LL long long
 6 #define INF 0x3f3f3f3f
 7 #define IN freopen("in.txt","r",stdin)
 8 #define OUT freopen("out.txt", "w", stdout)
 9 #define MAXN 100005
10 using namespace std;
11 #define A 0
12 #define B 1
13 struct Node{
14     int x, y, pos;
15 };
16 int n;
17 int f[205][205][2];
18 Node a[205], b[205];
19 int a0, b0;
20 int main()
21 {
22     //IN;
23     //OUT;
24     int T;
25     scanf("%d", &T);
26     while(T--){
27         scanf("%d
", &n);
28         char ch;
29         int x, y;
30         a0 = 0;
31         b0 = 0;
32         //scanf("%c", &ch);
33         for(int i = 1; i <= n; i++){
34             scanf("%c", &ch);
35             scanf("%d%d
", &x, &y);
36 
37             if(ch == 'A'){
38                 a0++;
39                 a[a0].x = x;
40                 a[a0].y = y;
41                 a[a0].pos = i;
42             }
43             else{
44                 b0++;
45                 b[b0].x = x;
46                 b[b0].y = y;
47                 b[b0].pos = i;
48             }
49         }
50         int i = 0, j = 0;
51         memset(f, INF, sizeof(f));
52         f[0][0][A] = 0;
53         f[0][0][B] = 0;
54         int s, t;
55         for(int i = 0; i <= a0; i++){
56             for(int j = 0; j <= b0; j++){
57                 t = f[i][j][A] - 10;
58                 s = f[i][j][A] - 10;
59                 for(int k = j + 1; k <= b0; k++){
60                     s = max(s + 10, b[k].x);
61                     t = max(t + 10, s + b[k].y);
62                     f[i][k][B] = min(f[i][k][B], t);
63                 }
64                 t = f[i][j][B] - 10;
65                 s = f[i][j][B] - 10;
66                 for(int k = i + 1; k <= a0; k++){
67                     s = max(s + 10, a[k].x);
68                     t = max(t + 10, s + a[k].y);
69                     f[k][j][A] = min(f[k][j][A], t);
70                 }
71             }
72         }
73         printf("%d
", min(f[a0][b0][A], f[a0][b0][B]));
74     }
75     return 0;
76 }
原文地址:https://www.cnblogs.com/macinchang/p/4747946.html