• bzoj1071


    题意:

    给你n个人,问最大可以选多少人,使题目给出的不等式成立

    题解:

    1. 先把所有点按A*h+B*v从小到大排序

    2. 枚举最小高度minH

    3. 从左到右枚举minV,每次minV+1转移时,将原答案集合中的在左边界上的点删除,然后把点向后扫描,把能加入的点加入集合。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    typedef long long LL;
    LL read()
    {
        LL a=0;char ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        a=a*10+ch-'0';
        ch=getchar();
        while(ch>='0'&&ch<='9')
         {
            a=a*10+ch-'0';
            ch=getchar();
         }
        return a;
    }
    const int maxn=5009; 
    const double eps=1e-8;
    struct point
    { 
        LL x,y; 
        bool operator<(const point &a) const
         {return x+y<a.x+a.y;} 
    } p[maxn],u,v;
    LL x[maxn],low,high; 
    int n,N,A,B,C,ans,best=0,remain;
    priority_queue<point> Q;
    bool cmp(point a, point b)
    { 
        return a.x<b.x;
    }
    void del()
    {
        N=1;
        for (int i=2;i<=n;i++)
         if (x[i]!=x[i-1])x[++N]=x[i];
    }
    int main()
    {
        freopen("team.in","r",stdin);
        freopen("team.out","w",stdout);
        remain=n=read();A=read();B=read();C=read();
        for (int i=1;i<=n;i++)
         {
            p[i].x=read()*A;
            x[i]=p[i].y=read()*B;
         }
        sort(x+1,x+n+1);
        del();
        sort(p+1,p+n+1,cmp);
        for (int i=1;i<=N;i++)
         {
            while (!Q.empty())Q.pop();
            ans=0;low=x[i];high=x[i]+C;
            for (int j=n;j;j--)
             {
                if (low <= p[j].y && p[j].y <= high)
                 {
                    u=p[j];
                    Q.push(u);
                    ans++;
                    if (low==p[j].y)remain--;
                 }
                while (!Q.empty())
                 {
                    v=Q.top();
                    if (v.x+v.y<=high+p[j].x)break;
                    Q.pop();
                    ans--;
                 }
                best=max(best,ans);
             }
            if (remain<=best) break;
         }
        printf("%d
    ",best);
        return 0;
    }
  • 相关阅读:
    NAT(网络地址转换)
    go从文件中读取json字符串并转换
    实现守护进程
    c++ uconcontext.h实现协程
    bzoj 1085骑士精神
    在线代码评测机
    基于时间轮的定时器
    内存管理(一)
    二叉树的先序中序后序(非递归)
    RDD操作
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8447972.html
Copyright © 2020-2023  润新知