PKU 1167 The Buses
问题:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1167
参考:
http://angels1.0.blog.163.com/blog/static/84580504200892072639857/
思路:
这题比我想象的要难好多,可以说,在看了别人AC代码之后,发现已经超越了我目前的能力
我自己的想法很简单,暴力搜索每条可能的路线,枚举每条路线的前两个点,DFS,结果始终是TLE
正确思路:
特别需要注意理解清楚题意: Buses on the same route arrive at regular intervals from 12:00 to 12:59 throughout the entire hour.
如果找出前两个点,那么这条路径上的后续点也必须存在
对输入进行预处理,找出所有可能的路径,并且按照路径中点的个数的多少降序排列(因为题意要求使得路线尽可能的少,所以首先搜索包含点个数最多的路径)
另外,还有一些简单的数学推导:
start - interval < 0 (1) [点start之前不能存在其他点]
59 - interval > start (2)
根据(1), (1)我们就可以知道start <= 29
代码中还有一处非常重要的减枝(不剪就会TLE):
只写 r_cnt+1>=min还是会TLE
代码(TLE):
代码:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1167
参考:
http://angels1.0.blog.163.com/blog/static/84580504200892072639857/
思路:
这题比我想象的要难好多,可以说,在看了别人AC代码之后,发现已经超越了我目前的能力
我自己的想法很简单,暴力搜索每条可能的路线,枚举每条路线的前两个点,DFS,结果始终是TLE
正确思路:
特别需要注意理解清楚题意: Buses on the same route arrive at regular intervals from 12:00 to 12:59 throughout the entire hour.
如果找出前两个点,那么这条路径上的后续点也必须存在
对输入进行预处理,找出所有可能的路径,并且按照路径中点的个数的多少降序排列(因为题意要求使得路线尽可能的少,所以首先搜索包含点个数最多的路径)
另外,还有一些简单的数学推导:
start - interval < 0 (1) [点start之前不能存在其他点]
59 - interval > start (2)
根据(1), (1)我们就可以知道start <= 29
代码中还有一处非常重要的减枝(不剪就会TLE):
只写 r_cnt+1>=min还是会TLE
1
/*
important pruning
*/
2 if (r_cnt + 1 + (left - routes[k].stops) / routes[k].stops >= min)
3 return ;
4
2 if (r_cnt + 1 + (left - routes[k].stops) / routes[k].stops >= min)
3 return ;
4
代码(TLE):
1
void
2 dfs( int begin, int cur_routes)
3 {
4 int i, j, k, diff, cur, next =- 1 ;
5 if (cur_routes > MAX_ROUTES || cur_routes >= min)
6 return ;
7 if (begin == - 1 ) {
8 min = cur_routes;
9 return ;
10 }
11 -- tm[begin];
12 cur = begin;
13 for (i = cur + 1 ; i < MAX_T; i ++ ) {
14 if (tm[i]) {
15 diff = i - begin;
16 /* check */
17 for (j = i; j < MAX_T; j += diff)
18 if ( ! tm[j])
19 break ;
20 if (j < MAX_T)
21 continue ;
22
23 for (j = i; tm[j] && j < MAX_T; j += diff)
24 -- tm[j];
25 for (k = begin + 1 ; k < MAX_T / 2 ; k ++ )
26 if (tm[k] && next ==- 1 )
27 next = k;
28 dfs(next, cur_routes + 1 );
29 for (j = i; j < MAX_T; j += diff)
30 ++ tm[j];
31 cur = i;
32 }
33 }
34 ++ tm[begin];
35 }
2 dfs( int begin, int cur_routes)
3 {
4 int i, j, k, diff, cur, next =- 1 ;
5 if (cur_routes > MAX_ROUTES || cur_routes >= min)
6 return ;
7 if (begin == - 1 ) {
8 min = cur_routes;
9 return ;
10 }
11 -- tm[begin];
12 cur = begin;
13 for (i = cur + 1 ; i < MAX_T; i ++ ) {
14 if (tm[i]) {
15 diff = i - begin;
16 /* check */
17 for (j = i; j < MAX_T; j += diff)
18 if ( ! tm[j])
19 break ;
20 if (j < MAX_T)
21 continue ;
22
23 for (j = i; tm[j] && j < MAX_T; j += diff)
24 -- tm[j];
25 for (k = begin + 1 ; k < MAX_T / 2 ; k ++ )
26 if (tm[k] && next ==- 1 )
27 next = k;
28 dfs(next, cur_routes + 1 );
29 for (j = i; j < MAX_T; j += diff)
30 ++ tm[j];
31 cur = i;
32 }
33 }
34 ++ tm[begin];
35 }
代码:
1
#include
<
stdio.h
>
2 #include < stdlib.h >
3 #include < string .h >
4 #define MAX_R 910
5 #define MAX_T 60
6 #define MAX_RT 17
7 struct Route {
8 int begin;
9 int interval;
10 int stops;
11 } routes[MAX_R];
12 int cnt, left, n, min, tm[MAX_T];
13
14 int
15 compare( const void * arg1, const void * arg2)
16 {
17 return (( struct Route * )arg2) -> stops - (( struct Route * )arg1) -> stops;
18 }
19
20 int
21 check( int begin, int interval)
22 {
23 int i;
24 for (i = begin; i < MAX_T; i += interval)
25 if ( ! tm[i])
26 return 0 ;
27 return 1 ;
28 }
29
30 void
31 init()
32 {
33 int i, j, tmp;
34 min = MAX_RT + 1 ;
35 cnt = 0 ;
36 left = n;
37 memset(tm, 0 , sizeof (tm));
38 for (i = 0 ; i < n; i ++ ) {
39 scanf( " %d " , & tmp);
40 ++ tm[tmp];
41 }
42 for (i = 0 ; i < 29 ; i ++ ) { /* 0<=begin<=29 */
43 if (tm[i]) {
44 for (j = i + 1 ; j < 59 - i; j ++ )
45 if (check(i, j)) {
46 routes[cnt].begin = i;
47 routes[cnt].interval = j;
48 routes[cnt ++ ].stops = 1 + ( 59 - i) / j;
49 }
50 }
51 }
52 qsort(routes, cnt, sizeof ( struct Route), compare); /* descend order */
53 }
54
55 void
56 dfs( int index, int r_cnt)
57 {
58 int i, k, j;
59 if (left == 0 ) {
60 min = min < r_cnt ? min : r_cnt;
61 return ;
62 }
63 for (i = index; i < cnt && routes[i].stops > left; i ++ );
64 for (k = i; k < cnt; k ++ ) {
65 /* important pruning */
66 if (r_cnt + 1 + (left - routes[k].stops) / routes[k].stops >= min)
67 return ;
68
69 if (check(routes[k].begin, routes[k].interval)) {
70 for (j = routes[k].begin; j < MAX_T; j += routes[k].interval) {
71 -- tm[j];
72 -- left;
73 }
74 dfs(k, r_cnt + 1 );
75 for (j = routes[k].begin; j < MAX_T; j += routes[k].interval) {
76 ++ tm[j];
77 ++ left;
78 }
79 }
80 }
81 }
82
83 int
84 main( int argc, char ** argv)
85 {
86 while (scanf( " %d " , & n) != EOF) {
87 init();
88 dfs( 0 , 0 );
89 printf( " %d\n " , min);
90 }
91 }
2 #include < stdlib.h >
3 #include < string .h >
4 #define MAX_R 910
5 #define MAX_T 60
6 #define MAX_RT 17
7 struct Route {
8 int begin;
9 int interval;
10 int stops;
11 } routes[MAX_R];
12 int cnt, left, n, min, tm[MAX_T];
13
14 int
15 compare( const void * arg1, const void * arg2)
16 {
17 return (( struct Route * )arg2) -> stops - (( struct Route * )arg1) -> stops;
18 }
19
20 int
21 check( int begin, int interval)
22 {
23 int i;
24 for (i = begin; i < MAX_T; i += interval)
25 if ( ! tm[i])
26 return 0 ;
27 return 1 ;
28 }
29
30 void
31 init()
32 {
33 int i, j, tmp;
34 min = MAX_RT + 1 ;
35 cnt = 0 ;
36 left = n;
37 memset(tm, 0 , sizeof (tm));
38 for (i = 0 ; i < n; i ++ ) {
39 scanf( " %d " , & tmp);
40 ++ tm[tmp];
41 }
42 for (i = 0 ; i < 29 ; i ++ ) { /* 0<=begin<=29 */
43 if (tm[i]) {
44 for (j = i + 1 ; j < 59 - i; j ++ )
45 if (check(i, j)) {
46 routes[cnt].begin = i;
47 routes[cnt].interval = j;
48 routes[cnt ++ ].stops = 1 + ( 59 - i) / j;
49 }
50 }
51 }
52 qsort(routes, cnt, sizeof ( struct Route), compare); /* descend order */
53 }
54
55 void
56 dfs( int index, int r_cnt)
57 {
58 int i, k, j;
59 if (left == 0 ) {
60 min = min < r_cnt ? min : r_cnt;
61 return ;
62 }
63 for (i = index; i < cnt && routes[i].stops > left; i ++ );
64 for (k = i; k < cnt; k ++ ) {
65 /* important pruning */
66 if (r_cnt + 1 + (left - routes[k].stops) / routes[k].stops >= min)
67 return ;
68
69 if (check(routes[k].begin, routes[k].interval)) {
70 for (j = routes[k].begin; j < MAX_T; j += routes[k].interval) {
71 -- tm[j];
72 -- left;
73 }
74 dfs(k, r_cnt + 1 );
75 for (j = routes[k].begin; j < MAX_T; j += routes[k].interval) {
76 ++ tm[j];
77 ++ left;
78 }
79 }
80 }
81 }
82
83 int
84 main( int argc, char ** argv)
85 {
86 while (scanf( " %d " , & n) != EOF) {
87 init();
88 dfs( 0 , 0 );
89 printf( " %d\n " , min);
90 }
91 }