给两个矩阵,其中数字由1到n*m,求两个矩阵的公共最大矩阵。。。
啊啊啊啊我好菜
#include<bits/stdc++.h>
using namespace std;
char str[1005];
int dp[1005][1005];
int a[1005][1005];
int b[1006][1006];
int sum[1006][1006];
int len[1006][1006];
struct MP
{
int x,y;
}mp[1005*1005];
int UP[1006],DOWN[1006];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&a[i][j]);
mp[a[i][j]]={i,j};
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&b[i][j]);
}
}
for(int i=n;i>=1;i--){
for(int j=1;j<=m;j++){
sum[i][j]=1;
MP pre=mp[b[i][j-1]];
MP now=mp[b[i][j]];
if(pre.x==now.x&&pre.y==now.y-1){
sum[i][j]+=sum[i][j-1];
}
len[i][j]=1;
MP up=mp[b[i+1][j]];
if(up.x==now.x+1&&up.y==now.y){
len[i][j]+=len[i+1][j];
}
}
}
int ans=0;
for(int i=1;i<=m;i++){
stack<int> s;
int j=1;
while(j<=n){
int ed=j+len[j][i];
for(;j<ed;j++){
if(s.size()==0||sum[s.top()][i]<=sum[j][i]){
s.push(j);
}else {
int top;
while(s.size()&&sum[s.top()][i]>sum[j][i]){
top=s.top();
int res=j-s.top();
ans=max(ans,res*sum[s.top()][i]);
s.pop();
}
s.push(top);
sum[top][i]=sum[j][i];
}
}
while(s.size()){
int res=ed-s.top();
ans=max(res*sum[s.top()][i],ans);
s.pop();
}
j=ed;
} while(s.size()){
int res=n-s.top()+1;
ans=max(res*sum[s.top()][i],ans);
s.pop();
}
}printf("%d",ans);
}
求最大矩阵是有两种方法,然鹅另外一种卡的莫名其妙,就学了现在这种,以后用这种单调栈求法吧,好菜啊啊啊啊。。。
upd;原来的方法是下标写错了。。。啊啊啊啊浪费了一个上午。。。
#include<bits/stdc++.h>
using namespace std;
char str[1005];
int dp[1005][1005];
int a[1005][1005];
int b[1006][1006];
int sum[1006][1006];
int len[1006][1006];
struct MP
{
int x,y;
}mp[1005*1005];
int UP[1006],DOWN[1006];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&a[i][j]);
mp[a[i][j]]={i,j};
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&b[i][j]);
sum[i][j]=1;
MP pre=mp[b[i][j-1]];
MP now=mp[b[i][j]];
if(pre.x==now.x&&pre.y==now.y-1){
sum[i][j]+=sum[i][j-1];
}
len[i][j]=1;
MP up=mp[b[i-1][j]];
if(up.x+1==now.x&&up.y==now.y){
len[i][j]+=len[i-1][j];
}
}
}
int ans=0;
for(int i=m;i>=1;i--){
stack<int> s;
sum[0][i]=0x3f3f3f3f;
s.push(0);
for(int j=1;j<=n;j++){//上向下
int now=j,down=j-1;
if(len[now][i]-1==len[down][i]){
while(s.size()>1&&sum[s.top()][i]>=sum[j][i])s.pop();
}else {
while(s.size())s.pop();s.push(j-1);
}
UP[j]=s.top();
s.push(j);
}
while(s.size())s.pop();
sum[n+1][i]=0x3f3f3f3f;
s.push(n+1);
int tim=0;
for(int j=n;j>=1;j--){//从下向上
int now=j,down=j+1;
if(len[now][i]==len[down][i]-1){
while(s.size()>1&&sum[s.top()][i]>=sum[j][i]){
s.pop();
}
}else {
while(s.size())s.pop();s.push(j+1);
}
DOWN[j]=s.top();
s.push(j);
}
for(int j=1;j<=n;j++){
ans=max(sum[j][i]*(DOWN[j]-UP[j]-1),ans);
}
}printf("%d",ans);
}