首页 > ACM题库 > HDU-杭电 > HDU 2859-Phalanx-动态规划-[解题报告]HOJ
2014
02-17

HDU 2859-Phalanx-动态规划-[解题报告]HOJ

Phalanx

问题描述 :

Today is army day, but the servicemen are busy with the phalanx for the celebration of the 60th anniversary of the PRC.
A phalanx is a matrix of size n*n, each element is a character (a~z or A~Z), standing for the military branch of the servicemen on that position.
For some special requirement it has to find out the size of the max symmetrical sub-array. And with no doubt, the Central Military Committee gave this task to ALPCs.
A symmetrical matrix is such a matrix that it is symmetrical by the “left-down to right-up” line. The element on the corresponding place should be the same. For example, here is a 3*3 symmetrical matrix:
cbx
cpb
zcc

输入:

There are several test cases in the input file. Each case starts with an integer n (0<n<=1000), followed by n lines which has n character. There won’t be any blank spaces between characters or the end of line. The input file is ended with a 0.

输出:

There are several test cases in the input file. Each case starts with an integer n (0<n<=1000), followed by n lines which has n character. There won’t be any blank spaces between characters or the end of line. The input file is ended with a 0.

样例输入:

3
abx
cyb
zca
4
zaba
cbab
abbc
cacq
0

样例输出:

3
3

点击打开链接

题意:

给你一个n*n的矩阵,矩阵中只含有26个小写字母,求其中最大的对称矩阵的大小

当我们算到s[i][j]时,每次我们只需要将它上方的和右方的依次比较,看是否相同

注意这里不能只比较s[i-1][j]和s[i][j+1],因为可能出现不符合的情况,如

zaba

cbab

abbc

cacq

当我们比较到红色的b的时候,如果只比较与他相邻的两个即绿色的b,就会从dp[i-1][j+1]多+1,而显然蓝色的部分不同

i!=0&&dp[i-1][j+1]>i-a时,dp[i][j]=dp[i-1][j+1]+1

i!=0&&dp[i-1][j+1]<i-a
(其中a为从当前位置找,找到的第一个不相等的x的位置,所以i-a就为最大的对称矩阵的长度)时,dp[i][j]=i-a;

当i==0时,dp[i][j]=1;




#include"stdio.h"
#include"string.h"
#define N 1001

int dp[N][N];
char s[N][N];

int main()
{
    int n;
    int i,j;
    int a,b;
    int ans;

    while(scanf("%d",&n)!=-1&&n)
    {
        getchar();
        for(i=0;i<n;i++)
            gets(s[i]);

        ans=0;
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                if(i==0)dp[i][j]=1;
                else
                {
                    a=i;
                    b=j;
                    while(s[a][j]==s[i][b])
                    {
                        a--;
                        b++;
                        if(a<0||b>=n)break;
                    }
                    a=i-a;
                    if(a>dp[i-1][j+1])
                        dp[i][j]=dp[i-1][j+1]+1;
                    else dp[i][j]=a;
                }
                if(dp[i][j]>ans)ans=dp[i][j];
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}


解题参考:http://blog.csdn.net/yangyafeiac/article/details/9445397


  1. 约瑟夫也用说这么长……很成熟的一个问题了,分治的方法解起来o(n)就可以了,有兴趣可以看看具体数学的第一章,关于约瑟夫问题推导出了一系列的结论,很漂亮