2020.7.21 T2最大子矩阵(jz暑假训练day6)

Description

我们将矩阵A中位于第i行第j列的元素记作A[i,j]。一个矩阵A是酷的仅当它满足下面的条件:
A[1,1]+A[r,s]<=A[1,s]+Ar,1
其中r为矩阵A的行数,s为矩阵A的列数。
进一步,如果一个矩阵是非常酷的仅当它的每一个至少包含两行两列子矩阵都是酷的。
你的任务是,求出一个矩阵A中的一个非常酷的子矩阵B,使得B包含最多元素。

Input

第一行包含两个整数R,S(2<=R,S<=1000),代表矩阵的行数与列数。
接下来R行每行包括S个整数,代表矩阵中的元素,矩阵中元素的绝对值不大于1000000。

Output

一行一个整数,代表子矩阵B的元素总数。如果没有一个非常酷的子矩阵,输出0。

Sample Input

输入1:
3 3
1 4 10
5 2 6
11 1 3
输入2:
3 3
1 3 1
2 1 2
1 1 1
输入3:
5 6
1 1 4 0 3 3
4 4 9 7 11 13
-3 -1 4 2 8 11
1 5 9 5 9 10
4 8 10 5 8 8

Sample Output

输出1:
9
输出2:
4
输出3:
15

【样例3解释】

在第三个样例中,子矩阵B的左上角为A[3,2],右下角为A[5,6]。

Data Constraint

对于60%的数据,满足R,S<=350。
对于100%的数据,满足2<=R,S<=1000,矩阵中元素的绝对值不大于1000000。

赛时

猜想对于一个矩阵,它里面所有2 * 2矩阵都是cool,那么它也是cool,赛后大佬给出证明(实际上十分简单)。
有个2 * 3的矩阵,假设其中2个2 * 2的矩阵都是合法:
a c e
b d f
由题意得到:
a+d<=c+b
c+f<=d+e
由于不等号相等,所有上下相加得:
a+d+c+f<=c+b+d+e
那么式子左右都有c+d,同时减去得:
a+f<=b+e
所以对于任何一个矩阵都能通过如此方式证明是否合法。
那么我们的问题简化,也就是对于一个矩阵(n-1) * (m-1)(因为2*2矩阵有这么多个),每个b[i][j]为1或0,对于一个内部都是1的矩阵,要求最大化。
考试时只想到了n3方,就是对于每2个列j,k,维护它们之间都是1时,底为i时,最多的行数,之后n3方转移。

正解

思想没错,现在考虑n方转移。
先n方预处理出来i,j最多向上延伸了几个1。之后对于每个行i,用个栈(单调上升)从前往后,从后往前O(n)求出此时的答案。说不清楚,看码

#include<cstdio>
#include<iostream>
#include<cstring>
#define N 1007
using namespace std;
int n,m,st[N],s[N][N],sum[N][N],ans,l[N],r[N];
bool bz[N][N];
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++){
		scanf("%d",&s[i][j]);
		if(i>=2&&j>=2){
			if(s[i-1][j-1]+s[i][j]<=s[i-1][j]+s[i][j-1])
				sum[i-1][j-1]=sum[i-2][j-1]+1;//预处理延伸的1的数量
		}
	}
	for(int i=1;i<n;i++){
		int cnt=1;
		st[cnt]=0;
		sum[i][0]=-1;
		sum[i][m]=-1;
		for(int j=1;j<m;j++){//顺序一遍
			while(cnt>0&&sum[i][j]<=sum[i][st[cnt]]) cnt--;//维护栈
			l[j]=st[cnt]+1;//记录最左边
			st[++cnt]=j;//进栈
		}
		cnt=1;
		st[cnt]=m;
		for(int j=m-1;j>=1;j--){//逆序一遍
			while(cnt>0&&sum[i][j]<=sum[i][st[cnt]]) cnt--;//维护栈
			r[j]=st[cnt]-1;//记录最右边
			st[++cnt]=j;//进栈
		}
		for(int j=1;j<m;j++)
			if(sum[i][j]) ans=max(ans,(sum[i][j]+1)*(r[j]-l[j]+2));
			//向上延伸的数量乘以距离,这里的两个因数都+1是因为目前的矩阵是n-1,m-1,我们要统计的应该是n,m的矩阵,所以要+1
	}
	printf("%d",ans);
}

猜你喜欢

转载自blog.csdn.net/jay_zai/article/details/107499935