藍橋 A Careful Approach 枚舉+貪心+二分

傳送門

思路:

一看到這個題目應該首先想到二分吧,最小問題最大化,最大問題最小化我們就考慮是否具有單調性是否能二分.

想完二分之後我們需要考慮如何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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章