原題連結
題解
太巧妙了
把每個點上方的連續f長度記錄下來,然後求每行的柱狀圖構成的矩形的最大面積
code
#include<bits/stdc++.h>
using namespace std;
int f[1005][1005]={0};
int n,m;
struct node
{
int h,cnt;
};
int solve(int row)//每一行列上的高度,如果全部使用,不是作為左端點就是作為右端點
{
int ans=0;
stack<node> q;//相當於求左邊最遠小於自己的值,右邊最遠小於自己的值,單調棧解法
for(int j=1;j<=m;j++)
{
int cnt=0;
while(q.size()&&q.top().h>=f[row][j])
{
cnt+=q.top().cnt;//cnt代表這個點收納了多少點
ans=max(ans,q.top().h*cnt);//作為左端點更新,即後邊遇到了比自己更小的值,然後彈出
q.pop();//如果彈出,代表遇到了作為左端點的最遠距離的點
}
ans=max(ans,f[row][j]*(cnt+1));//作為右端點更新,找到左邊比自己小的點
q.push({f[row][j],cnt+1});//cnt代表該元素左邊有多少不小於自己的(包括自己)
}
int cnt=0;
while(q.size())//有些元素沒有作為左端點更新過
{
ans=max(ans,(cnt+1)*q.top().h);
cnt+=q.top().cnt;
q.pop();
}
return ans;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
char op;
cin>>op;
if(op=='F') f[i][j]=f[i-1][j]+1;//記錄以該點為下端點,最長連續f的長度
}
}
int ans=0;
for(int i=1;i<=n;i++)
{
ans=max(ans,solve(i));//變成求每行的最大矩形
}
cout<<3*ans;
return 0;
}