题目描述
在一个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
View Code
很好的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; }