题意:从0到59分内,来了n辆公交车,求最少公交车路线。每条公交线的发车时间间隔都一样,且在这段时间内每条路线至少发车两次,公交车路线最多为17.
题解:预处理公交车可行路线的发车时间、间隔与车次,通过dfs求最小路线。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }