题意
你有一个1000*1000的矩阵,现在定义一个矩阵 $A_{x,y} $ 是酷的当且仅当 a 1 , 1 + a x , y < = a x , 1 + a 1 , y a_{1,1}+a_{x,y}<= a_{x,1}+a_{1,y} a1,1+ax,y<=ax,1+a1,y 且 x > 1 , y > 1 x>1,y>1 x>1,y>1 条件成立时。 而一个矩阵是非常酷的当且仅当它的所有子矩阵都是酷的。现在问你,非常酷的矩阵的最大的元素个数有多少。
做法
我们证明一下,假设有如下图,两边的矩阵都是单位酷矩阵(也是非常酷的矩阵)了,那么我们会有条件
a + d < = c + b a+d<=c+b a+d<=c+b 和 c + f < = e + d c+f<=e+d c+f<=e+d
我们将上面两个公式相加,会得到 a + f < = b + e a+f<=b+e a+f<=b+e,即对于一个新的矩阵来说,也是非常酷的。
那么我们就可以先算出所有2*2的子矩阵是否为酷的,如果是则标记为1,否则标记为0,就可以把问题转化成为一个求最大全1矩阵的问题。
然后就是板子的事情了。
代码
#include
#include
#define fi first
#define se second
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=1005;
int n,m,b[maxn][maxn],sum[maxn][maxn];
int a[maxn][maxn],ma[maxn],ans;
int read(){
int ans=0; char last=' ',ch=getchar();
while(ch<'0' || ch>'9')last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}
int s[maxn],top,L[maxn],R[maxn];
void fin(int r){
top=0; s[0]=0;
sum[r][m+1]=0;
for(int i=1;i<=m+1;i++){
int p=s[top];
while(sum[r][i]<sum[r][p]){
R[p]=i; top--;
p=s[top];
}
L[i]=p;
s[++top]=i;
}
rep(i,1,m){
if(sum[r][i]) ans=max(ans,(sum[r][i]+1)*(R[i]-L[i]));
}
}
int main(){
n=read(),m=read();
rep(i,1,n) rep(j,1,m) a[i][j]=read();
rep(i,1,n-1) rep(j,1,m-1){
if(a[i][j]+a[i+1][j+1]<=a[i+1][j]+a[i][j+1]) b[i][j]=1;
}
rep(i,1,n-1) rep(j,1,m-1) if(b[i][j]) sum[i][j]=sum[i-1][j]+1;
m--;
rep(i,1,n-1) fin(i);
printf("%d\n",ans);
return 0;
}