bzoj 1071: [SCOI2007]组队

Description

  NBA每年都有球员选秀环节。通常用速度和身高两项数据来衡量一个篮球运动员的基本素质。假如一支球队里

速度最慢的球员速度为minV,身高最矮的球员高度为minH,那么这支球队的所有队员都应该满足: A * ( height

– minH ) + B * ( speed – minV ) <= C 其中A和B,C为给定的经验值。这个式子很容易理解,如果一个球队的

球员速度和身高差距太大,会造成配合的不协调。 请问作为球队管理层的你,在N名选秀球员中,最多能有多少名

符合条件的候选球员。

Input

  第一行四个数N、A、B、C 下接N行每行两个数描述一个球员的height和speed

Output

  最多候选球员数目。

Sample Input

4 1 2 10

5 1

3 2

2 3

2 1

Sample Output

4

HINT

数据范围: N <= 5000 ,height和speed不大于10000。A、B、C在长整型以内。

2016.3.26 数据加强 Nano_ape 程序未重测

Source

一道火得冒烟的单调性的题目;

首先我们通过移项整理式子得到这样一个东西 A*height+B*speed<=C+A*minh+B*minv;

我们发现就算按正常套路我们固定一个minh再算一个还是没有单调性,那么我们只好minh和minv都枚举了;

我们假设外层枚举minv,内层枚举minh,那么A*height+B*speed在第二层枚举的时候是单调递增的,

那么我们用一个数组来按照A*height+B*speed来sort之后,那么合法的指针就是单调递增的了;

可是现在还有一个很严肃的问题,就是在这连续的合法区间中我们还要保证height>=minh,speed>=minv,这貌似是个三维偏序,肯定会TLE;

于是我们搞一个很骚的操作,我们先把满足一定条件的speed的加入,在删掉不合法的height;

加入speed合法的话,则minv<=speed<=minv+C/B,后面那个是因为如果speed>minv+C/B,那么A*height<A*minh,显然不行;

现在我们还需要删去height<minh的东西,我们发现如果我们按照上面的要求加入合法的speed的话,那么一定保证了A*height>A*minh‘‘(minh‘‘表示之前枚举过的某个minh)

所以删掉的数一定在之前枚举minh‘‘的时候加入过,只是这个时候因为minh变大了而变得不合法,所以不会删掉原本就没有加过的东西;

所以我们得到了一个O(n^2)的解决方案;

//MADE BY QT666
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=100050;
struct data{
    ll h,v,tot;
}g[N],g2[N],g3[N];
bool cmp1(const data &a,const data &b){return a.tot<b.tot;}
bool cmp2(const data &a,const data &b){return a.h<b.h;}
bool cmp3(const data &a,const data &b){return a.v<b.v;}
int main(){
    int n;ll A,B,C;
    cin>>n>>A>>B>>C;
    for(int i=1;i<=n;i++){
	scanf("%lld%lld",&g[i].h,&g[i].v);g[i].tot=A*g[i].h+B*g[i].v;
	g2[i].h=g[i].h,g2[i].v=g[i].v,g2[i].tot=g[i].tot;
	g3[i].h=g[i].h,g3[i].v=g[i].v,g3[i].tot=g[i].tot;
    }
    sort(g+1,g+1+n,cmp1);
    sort(g2+1,g2+1+n,cmp2);
    sort(g3+1,g3+1+n,cmp3);
    int ans=0;
    for(int i=1;i<=n;i++){
	int l1=0,l2=0;
	ll minv=g3[i].v;
	ll limv=minv+C/B;
	int cnt=0;
	for(int j=1;j<=n;j++){
	    ll limtot=C+A*g2[j].h+B*minv;
	    while(l1+1<=n&&g[l1+1].tot<=limtot){
		l1++;
		if(minv<=g[l1].v&&g[l1].v<=limv) cnt++;
	    }
	    while(l2+1<=n&&g2[l2+1].h<g2[j].h){
		l2++;
		if(minv<=g2[l2].v&&g2[l2].v<=limv) cnt--;
	    }
	    ans=max(ans,cnt);
	}
    }
    cout<<ans<<endl;
    return 0;
}
时间: 2024-10-01 05:07:54

bzoj 1071: [SCOI2007]组队的相关文章

(双指针) bzoj 1071

1071: [SCOI2007]组队 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1267  Solved: 392[Submit][Status][Discuss] Description NBA每年都有球员选秀环节.通常用速度和身高两项数据来衡量一个篮球运动员的基本素质.假如一支球队里速度最慢的球员速度为minV,身高最矮的球员高度为minH,那么这支球队的所有队员都应该满足: A * ( height – minH ) + B * ( sp

BZOJ 1073: [SCOI2007]kshort

二次联通门 : BZOJ 1073: [SCOI2007]kshort /* BZOJ 1073: [SCOI2007]kshort A* k短路 但是会爆一个点, 是卡A*的 */ #include <cstdio> #include <iostream> #include <cstring> #include <queue> #include <vector> #include <algorithm> #include <c

BZOJ 1071组队

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1071 题目很好,居然写了很久,题解找了真多: 主要两种做法: O(n^2lgn),通过优先堆维护,首先 等式变换:A*height+B*speed-C<=A*minheight+B*minspeed; 增加a[i].val=A*height+B*speed-C: 对a按height排序: 然后枚举i 把a[i].s作为min 1 /* **************************

[BZOJ 1066] [SCOI2007] 蜥蜴 【最大流】

题目链接:BZOJ - 1066 题目分析 题目限制了高度为 x 的石柱最多可以有 x 只蜥蜴从上面跳起,那么就可以用网络流中的边的容量来限制.我们把每个石柱看作一个点,每个点拆成 i1, i2,从 i1 到 i2 连一条边,容量为这个石柱 i 的高度,即跳跃次数限制.来到这个石柱就是向 i1 连边,从这个石柱跳起就是从 i2 向外连边,这样只要从石柱 i 跳起就一定会消耗 i1 到 i2 的边的容量.如果 i 有蜥蜴,就从 S 到 i1 连一条容量为 1 的边,如果从石柱 i 能跳出边界,就从

BZOJ 1072 [SCOI2007]排列perm

考虑到s的长度特别小,只有10,可以考虑状压dp. 设F[S][d]表示当选了集合S(用二进制压位表示)中的所有位置,对D取模的结果为d的方案总数:不难想到转移和初始化. 初始化:F[0][0]=1  0在这里表示空集合 转移:F[S][(d * 10 + s[i]-'0') % D]=sum{F[S0][d]}  S0是S的一个子集,并且刚好只比S少一个元素i 注意,重复的数字被算了多遍.样例当中就有.因此最后的答案要除以所有重复的数字个数的阶乘. 看代码就明白啦~ (再补充一个要用到状压技巧

BZOJ 1070: [SCOI2007]修车(最小费用最大流)

建图很神奇..建完图其实就是裸的费用流了.. -------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<vector> #include<queue> #define rep(i,n) for(int i

bzoj 1070: [SCOI2007]修车 -- 费用流

1070: [SCOI2007]修车 Time Limit: 1 Sec  Memory Limit: 128 MB Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小. 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间. Input 第一行有两个m,n,表示技术人员数与顾客数. 接下来n行,每行m个整数.第

bzoj 1068: [SCOI2007]压缩 DP

1068: [SCOI2007]压缩 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 496  Solved: 315[Submit][Status] Description 给一个由小写字母组成的字符串,我们可以用一种简单的方法来压缩其中的重复信息.压缩后的字符串除了小写字母外还可以(但不必)包含大写字母R与M,其中M标记重复串的开始,R重复从上一个M(如果当前位置左边没有M,则从串的开始算起)开始的解压结果(称为缓冲串). bcdcdcdcd可以

bzoj 1067: [SCOI2007]降雨量 模擬

1067: [SCOI2007]降雨量 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2010  Solved: 503[Submit][Status] Description 我们常常会说这样的话:“X年是自Y年以来降雨量最多的”.它的含义是X年的降雨量不超过Y年,且对于任意Y<Z<X,Z年的降雨量严格小于X年.例如2002,2003,2004和2005年的降雨量分别为4920,5901,2832和3890,则可以说“2005年是自2003年以