题意:从0到59分内,来了n辆公交车,求最少公交车路线。每条公交线的发车时间间隔都一样,且在这段时间内每条路线至少发车两次,公交车路线最多为17.

题解:预处理公交车可行路线的发车时间、间隔与车次,通过dfs求最小路线。

View Code
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 int n,tot[70],top,ans;
 6 struct Data
 7 {
 8     int start,ti,num;
 9     bool operator<(const Data &ne)const
10     {
11         return num>ne.num;
12     }
13     Data(){}
14     Data(int _st,int _ti,int _num){start=_st,ti=_ti;num=_num;}
15 }bus[1000];
16 bool check(int i,int t)
17 {
18     for(;i<60;i+=t)
19         if(tot[i]<=0)
20             return false;
21     return true;
22 }
23 void dfs(int k,int cnt)
24 {
25     if(n==0)
26     {
27         ans=cnt;
28         return;
29     }
30     for(;k<top;k++)
31     {
32         if(cnt+n/bus[k].num>=ans)
33             return;
34         if(check(bus[k].start,bus[k].ti))
35         {
36             for(int i=bus[k].start,ti=bus[k].ti;i<60;i+=ti)
37                 tot[i]--,n--;
38             dfs(k,cnt+1);
39             for(int i=bus[k].start,ti=bus[k].ti;i<60;i+=ti)
40                 tot[i]++,n++;
41         }
42     }
43 }
44 int main()
45 {
46     while(scanf("%d",&n)!=EOF)
47     {
48         memset(tot,0,sizeof(tot));
49         for(int tp,i=0;i<n;i++)
50             scanf("%d",&tp),tot[tp]++;
51         top=0;
52         for(int i=0;i<=29;i++)
53             if(tot[i])
54                 for(int j=i+1;i+j<60;j++)
55                     if(check(i,j))
56                         bus[top++]=Data(i,j,(59-i)/j+1);
57         sort(bus,bus+top);
58         ans=17;
59         dfs(0,0);
60         printf("%d\n",ans);
61     }
62     return 0;
63 }