思路:
一看到这个题目应该首先想到二分吧,最小问题最大化,最大问题最小化我们就考虑是否具有单调性是否能二分.
想完二分之后我们需要考虑如何check, 仅仅是简单的排序 check是不可行的,因为我们不太确定能够按哪个端点来排序一定是正确的.
进而观察到题目中说n <= 8。那么我们是否可以暴力枚举出每个飞机降落的顺序,然后在按照贪心的思想,对当前二分的答案,让每个飞机在能降落的情况下尽可能早的降,然后维护最优解即可.
这里的到达顺序可以用dfs来写,我是用next_permutation 来直接搞得全排列.
#include<bits/stdc++.h>
#define eps (1e-6)
using namespace std;
const int maxn = 10;
int num[maxn],pos[maxn];
struct node{
int a,b;
}s[maxn];
int n;
double ans ;
bool check(double len)
{
double x = s[pos[1]].a;
for(int i = 2;i <= n;++i)
{
x += len;
if(x > s[pos[i]].b)
return 0;
if(x < s[pos[i]].a)
x = s[pos[i]].a;
}
return 1;
}
int main()
{
int ca = 1;
while(~scanf("%d",&n))
{
if(n == 0) break;
for(int i = 1;i <= n;++i)
{
num[i] = i;
scanf("%d %d",&s[i].a,&s[i].b);
//s[i].a *= 60,s[i].b *= 60;
}
ans = 0;
do{
for(int i = 1;i <= n;++i)
{
pos[num[i]] = i;
}
/*for(int i = 1;i <= n;++i)
printf("%d",num[i]);
puts("");*/
double l = 0,r = 1440,mid;
while(r - l > eps)
{
mid = (l + r) / 2;
if(check(mid))
l = mid;
else
r = mid;
}
ans = max(ans,r);
}while(next_permutation(num + 1, num + 1 + n));
ans *= 60;
printf("Case %d: %d:%02d\n",ca++,(int)ans / 60,int(fmod(ans,60) + 0.5));
}
return 0;
}