原题链接

考察:线性dp

这也能dp系列,完全没想到.

注意这道题是检查子矩阵,所以不用围绕主矩阵的对角线检查.

思路:

        枚举子矩阵的左下角坐标,定义f[i][j]是以(i,j)为左下角坐标的最长对称边长.可以发现f[i][j]的最大边长最多为f[i-1][j+1]+1.三重循环枚举即可.

         这题的原思路是枚举左下角+二分,因为没想到右上角与左下角的关系,所以考虑一个个检查,但这样挺麻烦的.

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 const int N = 1010;
 5 int n,f[N][N];//求的是最大对称子矩阵的和 
 6 char mp[N][N]; 
 7 int main()
 8 {
 9     while(scanf("%d",&n)!=EOF&&n)
10     {
11         int ans = 0;
12         for(int i=1;i<=n;i++) scanf("%s",mp[i]+1);
13         for(int i=1;i<=n;i++)
14           for(int j=1;j<=n;j++)
15           {
16               f[i][j] = 1;
17               if(i-1>0&&i-1<=n&&j+1>0&&n>=j+1)
18               {
19                   int k = 0;
20                   while(k<=f[i-1][j+1]&&mp[i-k][j]==mp[i][j+k]) k++;
21                   f[i][j] = k;
22             }
23             ans = max(ans,f[i][j]);
24           }
25         printf("%d\n",ans);
26     }
27     return 0;
28 }