bzoj 1057 单调栈

首先我们可以枚举每个一点,然后向下一直拓展到不能拓展为止,然后向下拓展的同时我们可以算出来向左最多拓展的个数,用单调栈来维护一个上升的序列,这样就类似与悬线法找最大01子矩阵了,但是对于这题01交替来说,好多细节比较麻烦,所以我们可以采用另一种转换方法,对于一个01矩阵来说,一定满足一下两个条件中的一个:

  1:矩阵中所有0的点(i,j),i与j的奇偶相同,且对于所有1点(i,j),i与j的奇偶不同。

  2:矩阵中所有0的点(i,j),i与j的奇偶不同,且对于所有1点(i,j),i与j的奇偶相同。

  那么我们把所有满足1条件的点标号为1,满足2条件的点标号为0,这样,我们就求出标号矩阵的01子矩阵就行了,还是使用单调栈的方法求,但是这里的最大0矩阵和最大1矩阵都有可能成为答案,所以我们先求最大1矩阵,然后将矩阵取非(!),在求一遍更新答案就好了。

  至于正方形和矩形的求法是相同的,只是更新答案的方式不同,特别的,最大子方阵也可以用DP来求解,设w[i][j]为以(i,j)点为右下角的方阵的最大边长(面积),转移为w[i][j]=min(w[i-1][j-1],w[i][j-1],w[i-1][j])+1。

  反思:没有考虑到DP的方阵局限性。

/**************************************************************
    Problem: 1057
    User: BLADEVIL
    Language: C++
    Result: Accepted
    Time:2948 ms
    Memory:48168 kb
****************************************************************/
 
//By BLADEVIL
#include <cstdio>
#include <algorithm>
#define maxn 2010
#define sqr(x) x*x
 
using namespace std;
 
int a[maxn][maxn],w[maxn],s[maxn],f[maxn][maxn],map[maxn][maxn];
int top,n,m,ans1,ans2;
 
void calc()
{
    for (int j=1;j<=m;j++)
    {
        top=0;
        for (int i=1;i<=n;i++)
        {
            int minw=i;
            while (top&&s[top]>=f[i][j])
            {
                ans1=max(ans1,s[top]*(i-w[top]));
                ans2=max(ans2,sqr(min(s[top],i-w[top])));
                minw=w[top--];
            }
            s[++top]=f[i][j]; w[top]=minw;
        }
    }
 
}
 
int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++) 
        {
            scanf("%d",&a[i][j]);
            if ((i&1)==(j&1)&&a[i][j]||(i&1)!=(j&1)&&!a[i][j]) map[i][j]=1; else map[i][j]=0;
        }
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
            if (map[i][j]) f[i][j]=f[i][j-1]+1; else f[i][j]=0;
    calc();
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
            map[i][j]=!map[i][j];
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
            if (map[i][j]) f[i][j]=f[i][j-1]+1; else f[i][j]=0;
    calc();
    printf("%d\n%d\n",ans2,ans1);
    return 0;
}

 

 

posted on 2014-02-19 14:19  BLADEVIL  阅读(488)  评论(0编辑  收藏  举报