2 条题解

  • 0
    @ 2026-5-10 3:04:21

    我们很容易得到一个时间复杂度为 O(n3)O(n^{3}) 的方法:枚举minv\min vminh\min h,然后把所有球员枚举一边,统计可不可以。

    那么,如果我们先枚举 minh\min h ,然后我们可以可以通过这个不等式:

    AA ×\times ( hh - minh\min h )+ BB ×\times ( vv - minv\min v ) \le CC

    得到:

    minv\min v \ge ( CC - AA ×\times ( hh - minh\min h ))/ BB )

    然后算出每一个球员在 minh\min h 确定的情况下,minv\min v 在哪一个范围的时候,这个球员可以被选中。

    然后我们只要通过差分,然后枚举每一个 vv 找到最大值就可以了。

    其余的注释在代码里:(还有,我在代码中把速度用 ss 来表示速度)

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    
    const int M=5005;
    int n,A,B,C,h[M],hh[M],s[M],hs=1,ans=1;
    int cnt[M*2],smax;
    
    signed main()
    {
    	cin>>n>>A>>B>>C;
    	for (int i=1;i<=n;i++)
    		cin>>h[i]>>s[i],smax=max(smax,s[i]),hh[i]=h[i];
    	sort(hh+1,hh+1+n);
    	for (int i=2;i<=n;i++)
    		if (hh[i]!=hh[i-1])
    			hh[++hs]=hh[i];//这一步是把h排序并去重
    	for (int i=1;i<=hs;i++)
    	{
    		memset(cnt,0,sizeof(cnt));
    		for (int j=1;j<=n;j++)
    		{
    			if (h[j]>=hh[i]&&(A*(h[j]-hh[i]))<=C)
    			{
    				int tl;
    				if (B==0)
    					tl=1;
    				else
    					tl=max(1ll,s[j]-(C-A*(h[j]-hh[i]))/B);
    				//这说明第j个数当Smin在tl~s[j]中时这个球员都可以被入选 
    				cnt[tl]++,cnt[s[j]+1]--;//差分,做了前缀和之后就相当于把tl~s[j]的数值+1 
    			}
    		}
    		for (int j=2;j<=smax;j++)
    			cnt[j]+=cnt[j-1];//做前缀和
    		for (int j=1;j<=n;j++)
    			ans=max(ans,cnt[s[j]]);//统计答案
    	}
    	cout<<ans;
    	return 0;
    }
    
    • 0
      @ 2025-10-8 17:02:37

      原式为:A*(height-minh)+B*(speed-mins)<=C 变换一下可得: height-minh<=[C-B*(speed-mins)]/A; 假设mins确定,那对于每个球员,我们枚举每个minh,求出minh在哪个范围内时,这个球员会被选中,再累加,求出可使结果最大的minh

      #include<bits/stdc++.h>
      using namespace std;
      const int N=6000;
      typedef long long ll;
      ll s[N],h[N],change[N],sum[N*2];
      bool v[N*2];
      int main(){
          int n,a,b,c;scanf("%d%d%d%d",&n,&a,&b,&c);
          ll maxh=0,len=0;
          for(int i=1;i<=n;i++){
              scanf("%lld%lld",&h[i],&s[i]);
              maxh=max(maxh,h[i]);
              if(!v[s[i]])change[++len]=s[i],v[s[i]]=1;//去重,因为对于同一个mins,只需一次计算出最大的答案
          }
          sort(change+1,change+1+len);
          ll res=1;
          for(int i=1;i<=len;i++){
              for(int j=1;j<=maxh;j++) sum[j]=0;
              for(int j=1;j<=n;j++){
                  if(s[j]>=change[i]&&b*(s[j]-change[i])<=c){//当前的mins与当前的球员是否符合条件
                      ll flag=1;
                      if(a==0) flag=1;
                      else flag=max(flag,h[j]-(c-b*(s[j]-change[i]))/a);
                      sum[flag]++,sum[h[j]+1]--;
                  }
              }
              for(int j=1;j<=maxh;j++) sum[j]=sum[j-1]+sum[j];
              for(int j=1;j<=n;j++) res=max(res,sum[h[j]]);
          }
          printf("%lld",res);
      }
      
      • 1

      信息

      ID
      2724
      时间
      1000ms
      内存
      125MiB
      难度
      6
      标签
      递交数
      23
      已通过
      11
      上传者