bzoj 1071: [SCOI2007]组队

指针胡乱跳 

利用单调性降次

/**************************************************************
    Problem: 1071
    User: lxy8584099
    Language: C++
    Result: Accepted
    Time:2744 ms
    Memory:1064 kb
****************************************************************/
 
/*
    将式子拆开就是 C + A*minH + B*minV >= A*h + B*v 
    结构体 一个a按 h排序 b一个按 A*h+B*v排序
    外层随便顺序枚举minV 内层增序枚举 minH 
    指针p1从1开始 在b数组里面判断 A*h + B*v <= C + A*minH + B*minV
        其中有满足 v >= minV && 此 v 不会让h做负的贡献值(意思是v不会太大 
        ans++; 这里是算出所有 符合minV 和  C + A*minH + B*minV条件的 没有符合 minH 
    指针p2从1开始 在a数组里面判断 h< minH
        其中有满足 v >= minV && 此 v 不会让h做负的贡献值(意思是v不会太大 
        ans--; 在这里 h是小于 minH 但又符合minV 和  C + A*minH + B*minV条件的
        所以ans要减去这部分算进去了的 但又不符合条件的
*/
#include<cstdio> 
#include<algorithm> 
#define ll long long
using namespace std;
const int N=5050;
struct pp {ll h,v,s;} a[N],b[N]; 
inline bool cmp1(pp a,pp b) {return a.h<b.h;} 
inline bool cmp2(pp a,pp b) {return a.s<b.s;} 
inline int max(int a,int b) {return a>b?a:b;} 
ll A,B,C;
int ans,n;
int main()
{
    scanf("%d%lld%lld%lld",&n,&A,&B,&C);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld%lld",&a[i].h,&a[i].v);
        a[i].s=A*a[i].h+B*a[i].v; b[i]=a[i];
    }
    sort(a+1,a+n+1,cmp1); sort(b+1,b+n+1,cmp2);
    for(int minv=1;minv<=n;minv++) // 随便枚举minv 不放就按a顺序的来 
    {
        int p1=0,p2=0,res=0;ll ed=C/B+a[minv].v;
        for(int minh=1;minh<=n;minh++) // 从小到大枚举 minh
        {
            // ed就是v==minv==0的时候 满足原式子 B除过去就成 
            while(p1<n&&b[p1+1].s<=C+A*a[minh].h+B*a[minv].v) // bs单增 
                if(b[++p1].v>=a[minv].v&&b[p1].v<=ed) res++;
            while(p2<n&&a[p2+1].h<a[minh].h) // ah单增  
                if(a[++p2].v>=a[minv].v&&a[p2].v<=ed) res--;
            ans=max(ans,res);
        }
    }
    printf("%d\n",ans);
    return 0;
}

 

转载于:https://www.cnblogs.com/lxy8584099/p/10315296.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值