思路:
一看到這個題目應該首先想到二分吧,最小問題最大化,最大問題最小化我們就考慮是否具有單調性是否能二分.
想完二分之後我們需要考慮如何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;
}