http://acm.hdu.edu.cn/showproblem.php?pid=2859
二维dp: dp[i][j] = min(dp[i-1][j+1]+1, cnt); ans = max(ans, dp[i][j])
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1010;
const int inf = 0x3f3f3f3f;
int dp[maxn][maxn];
char str[maxn][maxn];
int n, ans;
int main()
{
//freopen("aa.in", "r", stdin);
//freopen("bb.out", "w", stdout);
while(scanf("%d", &n) && n)
{
for(int i = 0; i < n; ++i)
{
scanf("%s", str[i]);
}
ans = 1;
for(int i = 0; i < n; ++i)
{
dp[0][i] = 1;
}
for(int i = 1; i < n; ++i)
{
for(int j = 0; j < n; ++j)
{
int cnt = 0;
while(str[i-cnt][j] == str[i][j+cnt])
{
cnt++;
if(i - cnt < 0 || j + cnt >= n)
break;
}
if(cnt - 1 >= dp[i-1][j+1])
dp[i][j] = dp[i-1][j+1] + 1;
else
dp[i][j] = cnt;
ans = max(ans, dp[i][j]);
}
}
printf("%d\n", ans);
}
return 0;
}