[dp][二分答案]最大正方形

来源:互联网 发布:java包名可以大写 编辑:程序博客网 时间:2024/05/19 13:59

题意

在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长。

分析

本题可以二分枚举
预处理前缀和
二分边长
对每一个正方形容斥判断是否合法
O(n^2*logn)
也可以dp

if(dp[i][j])    dp[i][j]=1+min(dp[i-1][j-1],min(dp[i-1][j],dp[i][j-1]));

O(n^2)
代码都很短
看是可以看懂的吧

二分答案

#include<cstdio>#include<iostream>#define N 110using namespace std;int s[N][N],n,m,ans,p,l,r,mid;int Sum(int p,int q,int u,int v){    return s[u][v]-s[u][q-1]-s[p-1][v]+s[p-1][q-1];}bool Check(int x){    for(int i=n;i>=x;i--)        for(int j=m;j>=x;j--)            if(Sum(i-x+1,j-x+1,i,j)==x*x)return 1;    return 0;}int main(){    freopen("data.txt","r",stdin);    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++){            scanf("%d",&p);            s[i][j]=s[i][j-1]+s[i-1][j]-s[i-1][j-1]+p;        }    l=0; r=min(n,m);    while(l<r){        mid=(l+r)/2;        if(Check(mid)){            ans=mid;            l=mid+1;        }        else r=mid;    }    if(Check(l))ans=l;    printf("%d\n",ans);}

dp

#include<cstdio>#include<iostream>#define N 110using namespace std;int dp[N][N],n,m,ans;int main(){    freopen("data.txt","r",stdin);    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)            scanf("%d",&dp[i][j]);    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)            if(dp[i][j]){                dp[i][j]=1+min(dp[i-1][j-1],min(dp[i-1][j],dp[i][j-1]));                ans=max(ans,dp[i][j]);            }//  for(int i=1;i<=n;i++){//      for(int j=1;j<=m;j++)printf("%d ",dp[i][j]);//      printf("\n");//  }    printf("%d\n",ans);}

暂且这样吧(逃..)

原创粉丝点击