bzoj1071/洛谷P4165 组队 枚举

本文详细介绍了一种解决特定类型算法问题的双指针技巧,通过两个数组分别按高度和速度排序,使用双指针遍历并计算满足约束条件的最大球员数量。此方法巧妙地结合了数学不等式和数组操作,提高了算法效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

死国矣…

vvv表示速度,hhh表示高度,s=Ah+Bvs=Ah+Bvs=Ah+Bv,约束条件化为Ah+Bv≤C+Aminh+BminvAh+Bv \leq C+Aminh+BminvAh+BvC+Aminh+Bminv

搞两个数组,aaa按照hhh从小到大排序,bbb按照sss从小到大排序。

任意顺序枚举minvminvminv,开两个指针lllrrr,分别指着aaabbb的开头。

按照递增的顺序枚举minhminhminh

如果b(r)s≤C+Aminh+Bminvb(r)_s \leq C+Aminh+Bminvb(r)sC+Aminh+Bminv,就将rrr指针后移。如果minv≤b(r)v≤CB+minvminv \leq b(r)_v \leq \frac{C}{B}+minvminvb(r)vBC+minv(这个rrr是移动前的),就令当前统计的球员数量++

如果a(l)h&lt;minha(l)_h &lt; minha(l)h<minh,则将lll指针左移,并在左移前判断如果minv≤a(l)v≤CB+minvminv \leq a(l)_v \leq \frac{C}{B}+minvminva(l)vBC+minv

你可能会说,minv≤vminv \leq vminvv这个条件没问题,但是为什么一定要v≤CB+minvv \leq \frac{C}{B}+minvvBC+minv呢?

首先,若v≤CB+minvv \leq \frac{C}{B}+minvvBC+minv,则B(v−minv)≤CB(v-minv) \leq CB(vminv)C,对任意一个h&lt;minhh&lt;minhh<minh,都有A(h−minh)+B(v−minv)≤CA(h-minh)+B(v-minv) \leq CA(hminh)+B(vminv)C,我们不会减掉没有出现过的答案。

那为什么不在去除答案的时候判断s≤C+Aminh+Bminvs \leq C+Aminh+BminvsC+Aminh+Bminv呢?因为可能你移到某个lll时,依然a(l)s&gt;Aminh+Bminv+Ca(l)_s &gt; Aminh+Bminv+Ca(l)s>Aminh+Bminv+Ca(l)h&lt;minha(l)_h &lt; minha(l)h<minh,于是就没有减去贡献,就会使算出来的答案偏大。

#include<bits/stdc++.h>
using namespace std;
#define RI register int
const int N=5005;
int n,A,B,C,ans;
struct node{int v,h,s;}a[N],b[N];
bool cmp1(node x,node y) {return x.h<y.h;}
bool cmp2(node x,node y) {return x.s<y.s;}
int main()
{
	scanf("%d%d%d%d",&n,&A,&B,&C);
	for(RI i=1;i<=n;++i) {
		scanf("%d%d",&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+1+n,cmp1),sort(b+1,b+1+n,cmp2);
	for(RI i=1;i<=n;++i) {
		int minv=a[i].v,l=1,r=1,js=0;
		for(RI j=1;j<=n;++j) {
			int minh=a[j].h;
			while(r<=n&&b[r].s<=A*minh+B*minv+C) {
				if(b[r].v>=minv&&b[r].v<=C/B+minv) ++js;
				++r;
			}
			while(l<=n&&a[l].h<minh) {
				if(a[l].v>=minv&&a[l].v<=C/B+minv) --js;
				++l;
			}
			ans=max(ans,js);
		}
	}
	printf("%d\n",ans);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值