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.
  • 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 }
原文地址:https://www.cnblogs.com/SilverNebula/p/5862777.html