51Nod1158 全是1的最大子矩阵

题目看这里

想到了NOIP普及组当年那道题

做法非常显然,O(n^2)枚举矩形的上下边界,让后用一个dp+前缀和就搞定了

f[i]表示以第j列作为结尾的最大子矩形的宽,那么如果第i列在[l,r]的范围都是1,那么f[i]=f[i+1],否则f[i]=0

答案就是max{(r-l+1)*f[i]}

#pragma GCC opitmize("O3")
#pragma G++ opitmize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m,s[510][510],f[510],ans=0;
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j){
            scanf("%d",s[i]+j);
            s[i][j]+=s[i-1][j];
        }
    for(int i=1;i<=n;++i)
        for(int j=0;j<i;++j){
            for(int k=1;k<=m;++k){
                if(s[i][k]-s[j][k]==i-j) f[k]=f[k-1]+1; else f[k]=0;
                ans=max(ans,f[k]*(i-j));
            }
    }
    printf("%d\n",ans);
}

posted @ 2018-04-27 17:20  扩展的灰(Extended_Ash)  阅读(160)  评论(0编辑  收藏  举报