题目大意
有
n
个人在一条无穷的数轴上,一开始第
现在你最多可以删除
K
个人,最大化
题目分析
首先我们可以想到二分答案。那么怎么判定答案
t
是否可行呢?
可以发现,两个人没有相遇当且仅当在零时刻两人的相对顺序和
那么我们删掉最少的人=保留最多的人使得这些相对顺序不发生变化。
那可以一开始将所有人按照
pi
排序,然后判定时计算每个人的位置,做一个最长上升子序列就可以得到最多能保留的人数。
令
A
为二分上界,然后就
代码实现
使用lower_bound来实现LIS真短!
#include <algorithm>
#include <iostream>
#include <cfloat>
#include <cstdio>
#include <cctype>
using namespace std;
typedef long double db;
int read()
{
int x=0,f=1;
char ch=getchar();
while (!isdigit(ch)) f=ch=='-'?-1:f,ch=getchar();
while (isdigit(ch)) x=x*10+ch-'0',ch=getchar();
return x*f;
}
const db INF=2e+9;
const db EPS=1e-5;
const int N=100050;
int v[N],p[N],kth[N];
db f[N],x[N];
db ans;
int n,K;
bool judge(db t)
{
for (int i=1;i<=n;i++) x[i]=1.0*v[kth[i]]*t+1.0*p[kth[i]];
for (int i=1;i<=n;i++) f[i]=DBL_MAX/3;
f[0]=-DBL_MAX/3;
int len=0;
for (int i=1;i<=n;i++)
{
int id=lower_bound(f,f+len+1,x[i])-f;
f[id]=x[i],len=max(len,id);
}
return n-len<=K;
}
void binary_search()
{
for (db l=0.0,r=INF,mid;r-l>EPS;)
{
mid=(l+r)/2.0;
if (judge(mid)) l=(ans=mid)+EPS;
else r=mid-EPS;
}
}
bool cmp(int x,int y){return p[x]<p[y];}
int main()
{
freopen("monument.in","r",stdin),freopen("monument.out","w",stdout);
n=read(),K=read();
for (int i=1;i<=n;i++) p[i]=read(),v[i]=read(),kth[i]=i;
sort(kth+1,kth+1+n,cmp);
binary_search();
if (judge(ans+1.0)) printf("Forever\n");
else printf("%.4lf\n",(double)ans);
fclose(stdin),fclose(stdout);
return 0;
}