【题解】最大零矩阵

来源http://codevs.cn/problem/1159/
去年APUC计算概论考试的H题就由此变式而来,到时写了个自以为O(n^4)实际上n^6的枚举,自然没过,当时如果做出来有A=希望。考完srz神犇告诉我了O(n^3)的算法,并没有听懂。一直懒散,直到今天才研究了一下,发现有位省队爷写过论文,十分详尽。
《对最大全零子矩阵的研究》
http://wenku.baidu.com/link?url=BmVcU3ZfKTabjcsNzYHeOkYoHHCU1EnbGu4JKclaORpNcxxubAr0j9y-aYIL8uCwgyCAFC19SUDTnuDHEZLHAkIG6VrmSL7mbS4zKv_G3jG

想了想写出来了n^3的算法,显然是能过的,但是论文中的法6给我留下深刻印象,抽时间一定要实现一下。

自己写的算是法3吧,srz大神的方法,简单有效,尤其是将二维转化为一维的方法和部分和实现O(1)的判断,给我启发很大。

其实很多题目并没有那么难,这道典型的水题卡住我深刻说明了一些问题。

下面法3的AC代码。原题与H题略有不同。

#include
#include
#include
#include
#include
#include
using namespace std;

int f[2050][2050],ans,n;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
     {
        int b=0,x=0;
        for(int j=1;j<=n;j++)
         {
            cin>>x;
            if(!x)
            {
                b++;
                f[i][j]=b;
            }
            else b=0;
         }
     }

    for(int i=1;i<=n;i++)
     {
        for(int j=1;j<=n;j++)
         {  if(!f[i][j])
          continue;
            int p=i,q=i;
            while((p>1&&f[p][j])&&f[p-1][j]>=f[i][j])
            {
                p--;
            }
            while((q1][j]>=f[i][j])
            {
                q++;
            }
            ans=max(ans,(q-p+1)*f[i][j]);
         }
     } 
     cout<

你可能感兴趣的:(OI,枚举,部分和)