zoukankan      html  css  js  c++  java
  • bzoj1071 [SCOI2007]组队

    题目链接

    problem

    给出A,B,C和n个二元组(x,y)。
    问最多选多少个二元组使得所选二元组均满足(A imes (x-minx) + B imes (y - miny) le C)。其中(minx,miny)分别表示所选二元组中最小的x,y。

    solution

    将题目中的式子展开得:

    (Ax - Aminx + By - Bminy le C)

    (Ax + By le C + Aminx + Bminy)

    (s=Ax+By)。考虑枚举一个minx。然后从小到大枚举一个miny。

    将二元组分别按照s和y排序。用一个指针l在按s排序的数组中移动,表示满足(Ax+Byle C + Aminx + Bminy)的数量。用一个指针r在按y排序的数组中移动,表示满足(y ge miny)的位置。

    因为miny是从小到大枚举的,所以l会不断往右移动,当往右移动一步时,如果跨过位置的y>r所指的位置的y,就将ans++。因为即便当前位置不满足(yge miny),我们在后面移动r的时候还可以删掉他。然后显然r也是会不断往右移动,移动的过程中,如果发现跨过的位置被统计过答案了,就将ans--。然后就可以不充不漏的统计答案了。

    code

    /*
    * @Author: wxyww
    * @Date:   2019-12-14 08:43:08
    * @Last Modified time: 2019-12-14 10:21:15
    */
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<ctime>
    using namespace std;
    typedef long long ll;
    const int N = 5010;
    ll read() {
    	ll x = 0,f = 1;char c = getchar();
    	while(c < '0' || c > '9') {
    		if(c == '-') f = -1; c = getchar();
    	}
    	while(c >= '0' && c <= '9') {
    		x = x * 10 + c - '0'; c = getchar();
    	}
    	return x * f;
    }
    struct node {
    	int h,v; ll w;
    }a[N],b[N];
    bool cmp1(const node &A,const node &B) {
    	return A.w < B.w;
    }
    bool cmp2(const node &A,const node &B) {
    	return A.h < B.h;
    }
    int main() {
    	int n = read();ll A = read(),B = read(),C = read();
    	for(int i = 1;i <= n;++i) {
    		a[i].h = read(),a[i].v = read();
    		a[i].w = a[i].h * A + a[i].v * B;
    		b[i] = a[i];
    	}
    
    	sort(b + 1,b + n + 1,cmp1);
    	sort(a + 1,a + n + 1,cmp2);
    	int ans = 0;
    	for(int i = 1;i <= n;++i) {
    		int minV = a[i].v;int l = 0,r = 0,now = 0;
    		for(int j = 1;j <= n;++j) {
    			int minH = a[j].h;
    
    			while(b[l + 1].w <= C + A * minH + B * minV && l < n) {
    				++l;
    				if(b[l].v < minV) continue;
    				if(b[l].h > a[r].h) ++now;
    			} 
    			while(a[r + 1].h < minH && r < n) {
    				++r;
    				if(a[r].v < minV) continue;
    				if(a[r].w <= C + A * minH + B * minV) --now;
    			}
    			ans = max(ans,now);
    		}
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    
  • 相关阅读:
    Codeforces 1163E 高斯消元 + dfs
    Codeforces 1159E 拓扑排序
    Codeforces 631E 斜率优化
    Codeforces 1167F 计算贡献
    Codeforces 1167E 尺取法
    Gym 102007I 二分 网络流
    Codeforces 319C DP 斜率优化
    Codeforces 1163D DP + KMP
    Comet OJ
    Vue 的响应式原理中 Object.defineProperty 有什么缺陷?为什么在 Vue3.0 采用了 Proxy,抛弃了 Object.defineProperty?
  • 原文地址:https://www.cnblogs.com/wxyww/p/bzoj1071.html
Copyright © 2011-2022 走看看