Codeforces Round #513 by Barcelona Bootcamp C. Maximum Subrectangle(双指针+思维)

https://codeforces.com/contest/1060/problem/C

题意

给两个数组,a数组有n个元素,b数组有m个元素,两个数组元素互相相乘形成n*m的矩阵,找一个子矩阵,元素和<=x,子矩阵的面积尽量大,求这个子矩阵的面积大小

思路

  • 一开始往二维前缀和+暴力+查询之类想了,没观察规律,复杂度怎么想都不对
  • 规律其实就是

    子矩阵的和等于两个数组的连续子序列和相乘,面积大小等于子序列长度相乘

  • 即要在两个数组中找出两个连续的子序列,保证他们的和相乘<=x的情况下,长度的乘积尽量大
  • 暴力+双指针
  • 可以先处理出第一个数组,每个长度最小的值(n*n)
  • 然后枚举第一个数组的长度,用双指针找到第二个数组的长度(n*m)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll a[2005],b[2005],n,m,x,ans,s1,s2;
int i,j,l,r;
int main(){
    cin>>n>>m;
    for(i=1;i<=n;i++){scanf("%lld",&a[i]);a[i]=a[i-1]+a[i];}
    for(i=1;i<=m;i++)scanf("%lld",&b[i]);
    scanf("%lld",&x);
    ans=0; 
    for(i=1;i<=n;i++){
        s1=2e9;s2=b[1];
        for(j=1;j+i-1<=n;j++)s1=min(s1,a[j+i-1]-a[j-1]);
        l=r=1;
        while(r<=m){
            if(s1*s2<=x){
                ans=max((ll)(r-l+1)*i,ans);
                s2+=b[++r];
            }else s2-=b[l++];
        }
    }
    cout<<ans;
}

猜你喜欢

转载自www.cnblogs.com/VIrtu0s0/p/9985525.html