题目链接
这道题刷新了我对算法题的认知,算法,看上去是在处理数字,实际上实在解决实际问题(以上言论,和这道题无关)
这道题的的思路就是
:以每行为单位,求到当前行之上的最大连续面积,这个面积的计算方法:
和这道题的解题思路一样。
做题总结:
这是一道可以用单调栈解决的问题,为什么说它是用单调栈解决的问题呢?
因为这道题设计到对一个序列中的数字进行最小化处理,比如3 4 5,我把3 4 5 都看作3 再取做下步,这正是单调栈可以解决的。
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
int main()
{
int n,m;
int p;
int num[2019],ans;
int L[2019],R[2019];
while(scanf("%d%d",&m,&n)!=EOF)
{
memset(num,0,sizeof(num));
memset(L,0,sizeof(L));
memset(R,0,sizeof(R));
ans=0;
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&p);
if(p==1)
{
num[j]++;
}
else
num[j]=0;
}
//ת»¯ÎªÇó×î´óÃæ»ý¡£
//ÿһ¸ö×îÏÂÖµ£¬Ñ°ÕÒËü×óÃæºÍÓÒÃæ±ÈËü´óµÄÊý
//ÏÈÕÒ×óÃ棻
stack<int>s1;
s1.push(1);
L[1]=0;
for(int j=2;j<=n;j++)
{
L[j]=0;
while(!s1.empty()&&num[j]<=num[s1.top()])
{
L[j]+=L[s1.top()]+1;//Óм¸¸ö±ÈËü´ó
s1.pop();
}
s1.push(j);
}
//Ñ°ÕÒÓұ߱ÈËü´óµÄÊý¡£
stack<int>s2;
s2.push(n);
R[n]=0;
for(int j=n-1;j>=1;j--)
{
R[j]=0;
while(!s2.empty()&&num[j]<=num[s2.top()])
{
R[j]+=R[s2.top()]+1;
s2.pop();
}
s2.push(j);
}
int max,temp;
for(int j=1;j<=n;j++)
{
max=num[j]*(L[j]+R[j]+1);
if(max>ans)
ans=max;
}
}
printf("%d\n",ans);
}
return 0;
}