CodeForces - 589F(贪心+二分)

题意:

一个美食家来吃晚宴,有n道菜,每道菜上菜的时间和收盘子的时间分别是ai和bi,美食家想每道菜都吃,并且每道菜时间相同(吃一道菜的时间可以不连续),而且美食家每秒只能吃一道菜,问美食家吃菜最长的时间是多少。

思路:

先贪心,每次先吃收盘子最早的菜,这样影响最小,所以每道菜按bi有小到大排。再二分每道菜的吃的时间x,必须每道都吃,这答案n*x。

判断是否有x时间吃完这道菜,直接遍历每道菜的时间,并且这段时间前面没有用到(这里可以用数组标记下),每道都可以就时间往更大搜,不可以就往小搜。

代码:

 

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
struct node{
    int a,b;
}s[150];
int ans,n;
int vis[10050]; 
bool cmp(node a1,node a2)//按bi从小到大排 
{
    if(a1.b!=a2.b)
        return a1.b<a2.b;
    return a1.a<a2.a;
}

bool jug(int x)//判断每道菜x秒是否可行 
{
    memset(vis,0,sizeof(vis));//记录时间,是否访问 
    for(int i=0;i<n;i++)
    {
        int sum=0;
        for(int j=s[i].a;j<s[i].b;j++)
        {
            if(sum==x)
                break;
            if(!vis[j])
            {
                sum++;
                vis[j]=1;
            }
        }
        if(sum<x)//时间不够,则不行 
            return false;
    }
    return true;//时间够 
}
int solve()//二分每道菜的时间 
{
    int l=0,r=10000;
    while(l<=r)
    {
        int mid=(l+r)/2;
        if(jug(mid))
        {
            ans=mid;
            l=mid+1;
        }
        else
            r=mid-1;
    }
    return ans;
}
int main()
{
    ans=0;
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>s[i].a>>s[i].b;
    sort(s,s+n,cmp);
    cout<<n*solve()<<endl;
    return 0;    
} 

 

posted @ 2018-08-01 16:49  怀揣少年梦.#  阅读(253)  评论(0编辑  收藏  举报