【動態規劃】最大正方形 (洛谷 P1387 最大正方形)
阿新 • • 發佈:2018-02-14
代碼 log mar 最小 down 思路 計數 -m i++
-1,因為以fi,j-1為邊長做出的正方形依然在正方形i,j中。
輸入格式:
輸入文件第一行為兩個整數n,m(1<=n,m<=100),接下來n行,每行m個數字,用空格隔開,0或1。
輸出格式:
一個整數,最大正方形的邊長。
輸入輸出樣例
輸入樣例:
4 4
0 1 1 1
1 1 1 0
0 1 1 0
1 1 0 1
輸出樣例:
2
思路
設fi,j是以(i,j)為右下角的正方形的邊長。
簡單分析,fi,j應滿足fi,j = min( fi-1,j , fi-1,j-1 , fi,j-1 )+1;
這個比較抽象,設以(i,j)為右下角的正方形存在,邊長為fi,j,則以(i-1,j)(i-1,j-1)(i,j-1)為右下角的正方形也必然存在,並且最小邊長為fi,j
代碼很簡單,這裏用的C++來實現,但是有幾點要註意的地方:
- 註意第一行和第一列的元素沒有前一個元素。
- 如果某行某列中元素為0,那不存在以其為右下角的正方形,即fi,j=0;
#include <iostream>
using namespace std;
int min(int n1,int n2,int n3)
{
return (n1<n2?n1:n2)<n3?(n1<n2?n1:n2):n3;
}
int main()
{
int n,m; //n*m的0 1矩陣,(1<=n,m<=100)
int i,j,k; //i,j循環計數變量,k臨時變量
int f[100][100];
int maxn=1; //記錄最大正方形邊長
cin>>n>>m;
for(i=0;i<n;i++){
for(j=0;j<m;j++){
cin>>k;
if(k==0){
f[i][j]=0;
}else if(i==0 || j==0){
f[i][j]=1;
}else {
f[i][j]=min(f[i-1][j],f[i-1][j-1],f[i][j-1])+1;
if(f[i][j]>maxn){
maxn=f[i][j];
}
}
}
}
cout<<maxn;
return 0;
}
【動態規劃】最大正方形 (洛谷 P1387 最大正方形)