1. 程式人生 > >[洛谷1681]最大正方形II

[洛谷1681]最大正方形II

cst 邊界 思路 方程 ffffff style urn git 擴展

思路:
對於矩陣中的每一個元素,處理出它能擴展到的上邊界$up$、左邊界$left$,DP得出以該元素為右下角的最大正方形。
狀態轉移方程:$f_{i,j}=min(f_{i-1,j-1},up_{i,j},left_{i,j})$。

 1 #include<cstdio>
 2 #include<cctype>
 3 #include<algorithm>
 4 inline int getint() {
 5     char ch;
 6     while(!isdigit(ch=getchar()));
 7     int x=ch^
0; 8 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^0); 9 return x; 10 } 11 const int inf=0x7ffffffe; 12 int main() { 13 int n=getint(),m=getint(); 14 bool a[2][m+1]; 15 int up[2][m+1],left[2][m+1],f[2][m+1]; 16 f[1][0]=inf; 17 for(register int i=0
;i<=m;i++) f[0][i]=inf; 18 int ans=0; 19 for(register int i=1;i<=n;i++) { 20 for(register int j=1;j<=m;j++) { 21 a[i&1][j]=getint(); 22 up[i&1][j]=(i==1||a[i&1][j]==a[!(i&1)][j])?1:(up[!(i&1)][j]+1); 23 left[i&1][j]=(j==1
||a[i&1][j]==a[i&1][j-1])?1:(left[i&1][j-1]+1); 24 f[i&1][j]=std::min(f[!(i&1)][j-1]+1,std::min(up[i&1][j],left[i&1][j])); 25 ans=std::max(ans,f[i&1][j]); 26 } 27 } 28 printf("%d\n",ans); 29 return 0; 30 }

[洛谷1681]最大正方形II