1. 程式人生 > >Codeforces Round #513 by Barcelona Bootcamp C. Maximum Subrectangle(雙指標+思維)

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;
}