JZOJ 4944 【WC模拟】Monument

Monument

Description

N 个人,每个人的初始位置为pi,速度为 vi ,这些人在数轴上排成一排,现在最多可以消除 K 个人,设消除之后的T时间内都不会有人相撞,输出最大化的 T 。(若永远都不会有人相撞则输出Forever

Data Constraint

这里写图片描述

题解

考虑二分答案 T ,计算在T时间内至少需要删除多少人。
可以发现两个人在 T 时间之后内不相撞的充要条件为相对位置不改变。
先按照初始位置排序,i, j (pi < pj )两人可以共存仅当 T 时间后i依然在 j 前面。
那现在我们要保留尽量多的人,就是求该T时间后序列的最长上升子序列。设最长上升子序列的长度为 L ,则要删除的人数即为n- L <script type="math/tex" id="MathJax-Element-210">L</script>。

Code(Pascal)

const
    zd=1000001000;
var
    be:array[0..120000,1..2] of longint;
    cs:array[0..120000,1..2] of extended;
    cqy:array[0..120000] of extended;
    dy:array[0..120000] of extended;
    f:array[0..120000] of longint;
    n,m,j,k,l,i,o,ans:longint;
    le,ri,mid:extended;
function max(a,b:longint):longint;
    begin
        if a>b then exit(a) else exit(b);
    end;
function xz(p:extended):longint;
   var
       l,r,mid:longint;
   begin
       l:=0;
       r:=n+1;
       while l+1<r do
       begin
           mid:=(l+r) div 2;
           if dy[mid]<=p then l:=mid
           else r:=mid;
       end;
       exit(l);
   end;
procedure sjzl;
    var
        i,k:longint;
    begin
        randomize;
        for i:=1 to (n div 3)*2 do
        begin
            k:=random(n)+1;
            be[0]:=be[i];
            be[i]:=be[k];
            be[k]:=be[0];
        end;
    end;
procedure qsort(l,r:longint);
    var
        i,j,m:longint;
    begin
        i:=l;  j:=r;  m:=be[(l+r) div 2,1];
        repeat
            while be[i,1]<m do inc(i);
            while be[j,1]>m do dec(j);
            if i<=j then
            begin
                be[0]:=be[i];
                be[i]:=be[j];
                be[j]:=be[0];
                inc(i);  dec(j);
            end;
        until i>j;
        if l<j then qsort(l,j);
        if i<r then qsort(i,r);
    end;
begin
    readln(n,k);
    for i:=1 to n do  readln(be[i,1],be[i,2]);
    sjzl;  qsort(1,n);
    for i:=1 to n do  begin cs[i,1]:=be[i,1]; cs[i,2]:=be[i,2]; end;
    le:=0;
    ri:=zd;
    while le+0.0001<ri do
    begin
        mid:=(le+ri)/2;
        for i:=1 to n do
        begin
            cqy[i]:=mid*cs[i,2]+cs[i,1];
            dy[i]:=zd*10000000000.0;
        end;
        dy[0]:=0;
        ans:=0;
        for i:=1 to n do
        begin
            f[i]:=xz(cqy[i])+1;
            dy[f[i]]:=cqy[i];
            ans:=max(ans,f[i]);
        end;
        if ans>=n-k then le:=mid
        else ri:=mid;
    end;
    if (zd-le)<=0.0001 then writeln('Forever') else
    writeln(le:0:4);
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值