题目链接:http://codeforces.com/problemset/problem/589/F
题目翻译:
一个美食家走进宴会厅,厨师向客人推荐了n道菜。美食家知道每道菜的时间安排:每道菜何时上桌。
对于第i道菜,他在ai和bi(宴会开始后的几秒钟)的时间里知道了两个整数的时刻——厨师将第i道菜端进大厅,何时端出(ai < bi)。例如,如果ai = 10, bi = 11,那么第i道菜可以在一秒钟内吃完。
这些菜的数量很多,所以保证只要这道菜可以吃(即在大厅里),就不会用完。
美食家想尝试这n道菜肴,而不是冒犯任何厨师。正因为如此,美食家们想要在同样的时间里吃每一道菜。在吃的过程中,美食家可以立即在菜肴之间切换。他只允许在整数时刻在盘子之间切换。美食家只能同时吃一道菜。它可以在吃完其他的菜后再回到盘子里。
美食家希望在宴会上吃得尽可能久,不违反上述任何条件。你能帮他找出他在宴会上最多能吃多少菜吗?
输入
输入的第一行包含一个整数n(1≤n≤100)-宴会菜肴的数量。
以下n行包含了关于菜肴可用性的信息。第i个行包含两个整数ai和bi(0≤ai < bi≤10000)——瞬间变为可用时的第i个菜吃,当第i个菜就是离开大厅。
输出
输出必须包含唯一的整数-美食家在宴会上吃菜的最大总时间。
美食家可以即时地在菜肴之间切换,但只在整数时刻。它可以在吃完其他的菜后再回到盘子里。而且在每一个时刻,他只能吃一道菜。
解题思路:首先构建一个结构体,结构体的里定义每道菜的上菜时间与结束 时间,按照结束时间将其排序,定义一个visit数组,表示该时刻是否在食用某道菜,找到每道菜的可能的食用时间1<=t<=maxs(所有菜可食用的时间的最小值)在这个区间进行二分,找到能够符合题意的最大的值想x,最后输出x*n;
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=105;
struct st
{
int bn,en;
bool operator <(const st& a)
{
if(en!=a.en)
return en<a.en;
else
return bn<a.bn;
}
}stm[maxn];
int maxs=inf,ans=0;
int visit[10100],n;
bool jug(int a)
{
memset(visit,0,sizeof(visit));
int i,j,cnt;
for(i=0;i<n;i++)
{
cnt=0;
if(stm[i].en-stm[i].bn>=a)
{
for(j=stm[i].bn;j<stm[i].en;j++)
{
if(!visit[j])
{
cnt++;
visit[j]=1;
}
if(cnt==a)
{
// printf("j:%d cnt:%d\n",j,cnt);
break;
}
}
}
else
return false;
if(cnt!=a)
return false;
}
return true;
}
void bin_search()
{
int l,r;
l=1;
r=maxs;
int mid;
while(l<=r)
{
mid=(l+r)/2;
if(jug(mid))
{
ans=mid;
// printf("l:%d r:%d mid:%d\n",l,r,mid);
l=mid+1;
}
else
r=mid-1;
}
}
int main()
{
int i;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d%d",&stm[i].bn,&stm[i].en);
maxs=min(maxs,stm[i].en-stm[i].bn);
}
sort(stm,stm+n);
bin_search();
printf("%d",ans*n);
return 0;
}