POJ1167 The Buses
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 6234 | Accepted: 1698 |
Description
A man arrives at a bus stop at 12:00. He remains there during 12:00-12:59. The bus stop is used by a number of bus routes. The man notes the times of arriving buses. The times when buses arrive are given.
Find the schedule with the fewest number of bus routes that must stop at the bus stop to satisfy the input data. For each bus route, output the starting time and the interval.
- Buses on the same route arrive at regular intervals from 12:00 to 12:59 throughout the entire hour.
- Times are given in whole minutes from 0 to 59.
- Each bus route stops at least 2 times.
- The number of bus routes in the test examples will be <=17.
- Buses from different routes may arrive at the same time.
- Several bus routes can have the same time of first arrival and/or time interval. If two bus routes have the same starting time and interval, they are distinct and are both to be presented.
Find the schedule with the fewest number of bus routes that must stop at the bus stop to satisfy the input data. For each bus route, output the starting time and the interval.
Input
Your
program is to read from standard input. The input contains a number n (n
<= 300) telling how many arriving buses have been noted, followed by
the arrival times in ascending order.
Output
Your program is to write to standard output. The output contains one integer, which is the fewest number of bus routes.
Sample Input
17
0 3 5 13 13 15 21 26 27 29 37 39 39 45 51 52 53
Sample Output
3
Source
搜索。预处理出所有可能存在的公交线路,然后DFS,看选用其中的哪些可以正好使用到数据中的所有车各一次,且选用的线路最少。
剪枝1:由于这一小时里一种车至少来两次,所以只有30分以前来的才可能是始发车
剪枝2:对所有可能的公交线路按车停靠次数大小排序,如果当前选用线路数加上“剩余没安排的车除以当前线路需要的车”(即估计需要线路数)比答案大,剪枝
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 int ct[60];//ct[i]表示第i分钟到达的车数 8 int n,ans,tp;//车数 答案 总备选线路数 9 struct node{ 10 int s;//第一次到达时间 11 int j;//发车间隔 12 int t;//需要车数 13 }p[301]; 14 int cmp(node a,node b){ 15 return a.t>b.t; 16 } 17 bool test(int s,int ti){//s_起始时间 ti_间隔时间 18 for(int i=s;i<60;i+=ti) 19 if(!ct[i])return false; 20 return true; 21 } 22 void dfs(int t,int now){ 23 int i,j,k,tmp; 24 if(n==0){ 25 if(now<ans)ans=now; 26 return; 27 } 28 for(i=t;i<=tp && p[i].t>n;i++);//寻找合适线路,排除需要车数比剩余车数大的线路 29 for(k=i;k<=tp;k++){ 30 if(now+n/p[k].t>=ans)return;//剪枝 31 if(test(p[k].s,p[k].j)){ 32 tmp=p[k].j; 33 for(j=p[k].s;j<60;j+=tmp){ 34 ct[j]--; 35 n--; 36 } 37 dfs(k,now+1); 38 for(j=p[k].s;j<60;j+=tmp){ 39 ct[j]++; 40 n++; 41 } 42 } 43 } 44 } 45 int main(){ 46 scanf("%d",&n); 47 int i,j,a; 48 for(i=1;i<=n;i++){ 49 scanf("%d",&a); 50 ct[a]++; 51 } 52 tp=0; 53 for(i=0;i<=29;i++){ 54 if(!ct[i])continue; 55 for(j=i+1;j<=59-i;j++){ 56 if(test(i,j)){ 57 tp++; 58 p[tp].s=i; 59 p[tp].j=j; 60 p[tp].t=1+(59-i)/j; 61 } 62 } 63 } 64 sort(p+1,p+tp+1,cmp); 65 ans=17; 66 dfs(1,0); 67 printf("%d",ans); 68 return 0; 69 }
本文为博主原创文章,转载请注明出处。