8.19 T2

Solution

把原来的pos排序,二分时间 t ,然后更新成新的pos’ ,再排序比较二者顺序是否完全相同。

疑难:对k不会处理 60 pts

std: 其实就差一点想到正解。。。我们对新的pos’ 求出最长上升子序列LIS , 然后 若序列长度>=n-k 就可行

(n^2暴力枚举任意两个点相撞时间,取min可以90分。。。痛心)


60分

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=50005;
int n,k;
double ans;
struct node{
     double p,v;int id,rk;
}a[N],b[N];
bool cmp(node a,node b) {
    return a.p==b.p?a.id<b.id:a.p<b.p;
}
bool check(double t) {
    for(int i=1;i<=n;i++) {
        b[i]=a[i];
        b[i].p=a[i].p+a[i].v*t;
    }
    sort(b+1,b+1+n,cmp);
    for(int i=1;i<=n;i++)
        if(b[i].rk!=i) return 0;
    return 1;
}
int main() {
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++) {
        scanf("%lf%lf",&a[i].p,&a[i].v);
        a[i].id=i;
    }
    sort(a+1,a+1+n,cmp);
    for(int i=1;i<=n;i++)
        a[i].rk=i;
    
    double l=0,r=1000000;
    while(l<=r) {
        double mid=(l+r)/2.0;
        if(check(mid)) ans=mid,l=mid+0.00001;
        else r=mid-0.00001;
    }       
    if(ans>=999999) puts("Forever");
    else printf("%.4lf",ans);
    return 0;
}

100分

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long double ld;
const int N=1e5+5;
const ld eps=1e-4;
const ld inf=1e12;
int n,k;
struct node{
    ld p,v;
    int id;
    bool operator < (const node &x) const {
        return p<x.p;
    }
}a[N],b[N];
inline void Max(int &x,int y) {if(x<y)x=y;}
int c[N];
int query(int x) {
    int res=0;
    for(int i=x;i;i-=i&(-i))
        Max(res,c[i]);
    return res;
}
void upd(int x,int v) {
    for(int i=x;i<=n;i+=i&(-i))
        Max(c[i],v);   
}
inline bool check(ld t) {
    memset(c,0,sizeof(c));
    for(int i=1;i<=n;++i)
        b[i].p=a[i].p+a[i].v*t,b[i].id=i;
    sort(b+1,b+n+1);
    for(int i=1;i<=n;++i)
        a[b[i].id].id=i;
    for(int i=1;i<=n;++i) {
        int x=a[i].id;
        int y=query(x-1);
        upd(x,y+1);
    }
    return query(n)>=n-k;
}
int main() {
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;++i)
        scanf("%Lf%Lf",&a[i].p,&a[i].v);
    sort(a+1,a+n+1);
    ld l=0,r=inf,mid;
    while(abs(l-r)>eps*eps){
        mid=(l+r)/2;
        if(check(mid)) l=mid;
        else r=mid;
    }
    if(abs(mid-inf)<=eps) puts("Forever");
    else printf("%.4Lf",mid);
    return 0;
}


posted @ 2020-08-19 16:55  ke_xin  阅读(15)  评论(0编辑  收藏  举报