组队
又是一道考场上离正确结论只差半步,看了题解之后恍然大悟,回头一看交了个暴力的题目。就很弱。
可以想到暴力。用 \(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;
}
一如既往,万事胜意