题意:
一个美食家来吃晚宴,有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; }