题目链接:Codeforces - Maximum Subrectangle
考虑求子矩形的方法:二维前缀和,分别求出列和行的前缀和,然后再相乘。
第二种:矩形左上角(a,b),右下角(c,d)
那么对于数组sx,sy都是对应方向上面的前缀和。
sum = (sx[c]-sx[a-1])*(sy[d]-dy[b-1])
第一种很难求矩形的最小值,但是第二种方法,如果我们求出长度为i的x轴的最小值,和长度为j的y轴的最小值。
那么我们要找一个大小为i*j的矩形,直接两个最小值相乘即可。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=2e3+10;
int n,m,a[N],b[N],x,lx[N],ly[N],res;
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i],a[i]+=a[i-1];
for(int i=1;i<=m;i++) cin>>b[i],b[i]+=b[i-1];
memset(lx,0x3f,sizeof lx),memset(ly,0x3f,sizeof ly);
for(int i=1;i<=n;i++) for(int j=i;j<=n;j++) lx[i]=min(lx[i],a[j]-a[j-i]);
for(int i=1;i<=m;i++) for(int j=i;j<=m;j++) ly[i]=min(ly[i],b[j]-b[j-i]);
cin>>x;
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(1LL*lx[i]*ly[j]<=x){
res=max(res,i*j);
}
cout<<res;
return 0;
}