【洛谷习题】最大正方形

题目链接:https://www.luogu.org/problemnew/show/P1387


最近学OI有点过火,今早上愣是没睡醒,上午的自习就没有了!不过还是很开心,连A三道DP水题。

这个题的话,思路比较清晰。我们想知道有没有边长为l的正方形,肯定要先知道有没有边长为l-1的正方形。我们枚举一个正方形的左上角,然后搬着一个边长为l-1的正方形在四个角上跑,如果这四个角上的小正方形全是1,那么这个边长为l的正方形肯定也全是1,否则取其中最大的。描述的有点凌乱,看代码就好了。一开始傻了一般开了一个四维数组保存正方形的四个顶点,这样是没有必要的,因为一个左上角的顶点和边长就能确定一个正方形。

 1 #include<cstdio>
 2 inline int max(int a,int b) {return a>b?a:b;}
 3 inline int min(int a,int b) {return a<b?a:b;}
 4 const int mmax=105;
 5 int n,m,map[mmax][mmax],dp[mmax][mmax][mmax],ans=1;
 6 int main() {
 7     scanf("%d%d",&n,&m);
 8     for(int i=1;i<=n;++i)
 9         for(int j=1;j<=m;++j) {
10             scanf("%d",&map[i][j]);
11             if(map[i][j]) dp[i][j][1]=1;
12         }
13     for(int l=2;l<=min(n,m);++l) {
14         for(int i=1;i<=n-l+1;++i)
15             for(int j=1;j<=m-l+1;++j) {
16                 if(dp[i][j][l-1]==l-1&&dp[i][j+1][l-1]==l-1&&dp[i+1][j][l-1]==l-1&&dp[i+1][j+1][l-1]==l-1)
17                     dp[i][j][l]=l;
18                 else dp[i][j][l]=max(dp[i][j][l-1],max(dp[i][j+1][l-1],max(dp[i+1][j][l-1],dp[i+1][j+1][l-1])));
19                 ans=max(ans,dp[i][j][l]);
20             }
21         if(ans<l) break;
22     }
23     printf("%d",ans);
24     return 0;
25 }
AC代码

猜你喜欢

转载自www.cnblogs.com/Mr94Kevin/p/9613417.html