Time Limit: 2 Sec Memory Limit: 128 MB
Description
We
often use the matrix to analyze reality models. There are lots of
algorithm about matrix in Linear Algebra like matrix multiplication,
matrix determinant and matrix inversion, etc.
Recently, I should use matrix to do structural mechanics analysis.
The element in the matrix indicating the mechanical properties of each
unit in the structure. Stable sub-structure means a part with same
mechanical properties. I want to find the largest stable sub-struture as
it has good engineering applications. Reflected in the matrix, the
problem above equals to find the largest sub-matrix whose members have
the same value.
To accomplish the task perfectly, I wish you can help me to design a good algorithm to solve this problem.
Input
There are multiple test cases.
The first line contains two integers N and M, indicating the size of this N * M matrix A.
The next N line, each line containing M integers. The j-th integer in the i-th line means the element A(i, j).
1 <= N, M <= 800
1 <= A(i, j) <= 1000
Output
For each test, output the size of the largest sub-matrix satisfied the requests.
Sample Input
Sample Output
1
4
HINT
Source
Solution
单调栈
Implementation
#include <cstdio>
#include <stack>
using namespace std;
typedef long long LL; const int N(+); int h[N], L[N], R[N], a[N][N]; stack<int> st;
//[L[i], R[i])
int mono_stack(int l, int r){
for(; st.size(); st.pop());
for(int i=l; i<r; i++){
for(; !st.empty()&&h[st.top()]>=h[i]; st.pop());
if(st.empty()) L[i]=l;
else L[i]=st.top()+;
st.push(i);
}
for(; st.size(); st.pop());
for(int i=r-; i>=l; i--){
for(; !st.empty() && h[st.top()]>=h[i]; st.pop());
if(st.empty()) R[i]=r;
else R[i]=st.top();
st.push(i);
}
int res=;
for(int i=l; i<r; i++)
res=max(res, h[i]*(R[i]-L[i]));
return res;
} void solve(int n, int m){
int res=;
for(int i=; i<n; i++){
if(i==) for(int j=; j<m; j++) h[j]=;
else for(int j=; j<m; j++)
if(a[i][j]==a[i-][j]) h[j]++;
else h[j]=;
//two-pointers
for(int l=, r; l<m; l=r){
for(r=l+; r<m && a[i][r]==a[i][l]; r++);
res=max(res, mono_stack(l, r));
}
}
printf("%d\n", res);
} int main(){
for(int n, m; ~scanf("%d%d", &n, &m); ){
for(int i=; i<n; i++)
for(int j=; j<m; j++)
scanf("%d", a[i]+j);
solve(n, m);
}
return ;
}