P1387 最大正方形 图DP

题目描述

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

输入输出格式

输入格式:

输入文件第一行为两个整数n,m(1<=n,m<=100),接下来n行,每行m个数字,用空格隔开,0或1.

输出格式:

一个整数,最大正方形的边长

输入输出样例

输入样例#1: 复制
4 4
0 1 1 1
1 1 1 0
0 1 1 0
1 1 0 1
输出样例#1: 复制2


很好的dp题目 一般这种二维图的dp都是以横纵坐标为状态 注意不能设置dp[i][j] 矩形i j内最大正方形 而是以ij为右下角点的最大正方形 正方形的右下角肯定在1-n&&1-m中 所以就枚举完了所有情况
注意转移方程细节:
#include<bits/stdc++.h>
using namespace std;
//input
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m);
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define LL long long
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define N 500+5
#define inf 0x3f3f3f3f
int mp[N][N];
int dp[N][N];
int main()
{
    int n,m;
    RII(n,m);
    rep(i,1,n)
    rep(j,1,m)
    RI(mp[i][j]);
    int ans=0;
    rep(i,1,n)
    rep(j,1,m)
    if(mp[i][j])
    {
        dp[i][j]= min(min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;//之所以加上dp[i-1][j-1]是为了特判:上为1 左为1的时候 要考虑到中间的值   
        if(dp[i][j]>ans)ans=dp[i][j];
    }
    cout<<ans;
}
View Code







原文地址:https://www.cnblogs.com/bxd123/p/10518678.html