POJ 1167

题意:从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 }

你可能感兴趣的:(poj)