要求:一个n*n的字符矩阵,求一个满足以左下角元素和右上角元素练成的对角线为对称轴的最大子方阵边长。
方法:简单dp
1.状态:dp[i][j]表示以第i行第j列元素为子方阵的左下角元素的满足题意的最大子矩阵边长。
2.状态转移方程为:dp[i][j] = min(dp[i-1][j+1] , m + 1)。
m:(i,j)到(0,j) 和 (i,j)到(i,n-1)的最大相同元素。
3.重点还是状态和状态转移方程!!!!!!
4.好久不见的1A!
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
char map1[1005][1005] ;
int dp[1005][1005] ;
int main()
{
int i , j , n , p , q , cnt , ans ;
char s[1005] ;
while(scanf("%d" , &n)&&n != 0)
{
for(i = 0 ; i < n ; i ++)
{
scanf("%s" , &s) ;
for(j = 0 ; j < n ; j ++)
{
map1[i][j] = s[j] ;
}
}
memset(dp , sizeof(dp) , 0) ;
ans = 0 ;
for(i = 0 ; i < n ; i ++)
{
for(j = 0 ; j < n ; j ++)
{
p = i , q = j ;//p表示第j列第i行上面的元素
//q表示第i行第j列后面的元素
cnt = 0 ;
while(p >= 0 && q < n)
{
if(map1[p][j] == map1[i][q])
{
p -- ;
q ++ ;
}
else
{
cnt = q - j ;
break ;
}
}
if(! cnt)
{
cnt = min(i + 1 , n - j) ;
}
if(i - 1 >= 0 && j + 1 < n)
dp[i][j] = min(cnt , dp[i-1][j+1] + 1) ;
else
dp[i][j] = 1 ;
ans = max(ans , dp[i][j]) ;
}
}
printf("%d\n" , ans);
}
}