组队

link

又是一道考场上离正确结论只差半步,看了题解之后恍然大悟,回头一看交了个暴力的题目。就很弱。

可以想到暴力。用 \(f[i][j]\) 来代表以i为最小高度、j为最小速度的方案数,我们要做的就是把每一个人带进去看是否符合情况即可。 \(O(N^3)\) ,40分。

然后发现可以优化。观察方程:

\[A(a_i-H)+B(b_i-V)\le C \]

展开整理得到:

\[V\ge\frac{Aa_i-HA+Bb_i-C}{B} \]

枚举想到H和i,于是不等号右边就成了一个常量,所以所有满足

\[\frac{Aa_i-AH+Bb_i-C}{B}\le V\le b_i \]

的V都是可以被i这个人适合的。所以就变成了区间加单次统计,用差分数组即可。

要注意的是枚举的适合要预先判断 \(a_i\) 和H的关系是否合法,并且在差分的时候判断得出的左右端点是否构成一个合法区间,这一点很重要。

#include<bits/stdc++.h>
//#define zczc
#define int long long
const int N=5010;
const int S=10010;
using namespace std;
inline void read(int &wh){
    wh=0;int f=1;char w=getchar();
    while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
    while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
    wh*=f;return;
}
inline int max(int s1,int s2){
	return s1<s2?s2:s1;
}

int m,n,sa,sb,sc,ans,a[N],b[N],s[N],cnt[S];

signed main(){
	
	#ifdef zczc
	freopen("in.txt","r",stdin);
	#endif
	
	read(m);read(sa);read(sb);read(sc);
	for(int i=1;i<=m;i++){
		read(a[i]);read(b[i]);
		s[i]=a[i];
	}
	sort(s+1,s+m+1);
	n=unique(s+1,s+m+1)-s-1;
	for(int i=1;i<=n;i++){
		int mh=s[i];
		memset(cnt,0,sizeof(cnt));
		for(int j=1;j<=m;j++){
			if(a[j]<mh)continue;
			int res=b[j]+(sa*a[j]-sa*mh-sc)/sb;
			if(max(res,1)>b[j]+1)continue;
			cnt[b[j]+1]--;cnt[max(res,1)]++;
		}
		for(int i=1;i<S;i++){
			cnt[i]+=cnt[i-1];
			ans=max(ans,cnt[i]);
		}
	}
	printf("%lld",ans);
	
	return 0;
}
posted @ 2022-06-22 14:02  Feyn618  阅读(158)  评论(0编辑  收藏  举报