HDU 2859—Phalanx(DP)

Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

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

Input

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.

Output

Each test case output one line, the size of the maximum symmetrical sub- matrix.

Sample Input

3 abx cyb zca 4 zaba cbab abbc cacq 0

Sample Output

3 3

 

大意:

给定一个矩阵,求最大对称矩阵

思路:

一开始怎么想也觉得不会有状态转移的情况,即使有也会复杂度过高

后来看了题解才想通,其实和我一开始的想的有些相似,因为给的时间比较长,n^3的复杂度也会死可以接受的

试想一个n阶的对称阵如何变成n+1的对称阵?

在它的两个底边追加对称的元素即可,对角线元素添加任意元素即可

于是,我们从一个点向他的上与右边推进,直至不匹配

将匹配的个数与dp[i-1][j+1]比较,

如果匹配量大于右上角记录下来的矩阵大小,就是右上角的数值+1,否则就是这个匹配量。

代码:

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1300;
char m[MAXN][MAXN];
int dp[MAXN][MAXN];
int main()
{
    //freopen("data.in","r",stdin);
    int n;
    while(~scanf("%d",&n)&&n){
        getchar();
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                scanf("%c",&m[i][j]);
            }
            getchar();
        }
//        for(int i=0;i<n;i++){
//            for(int j=0;j<n;j++){
//                cout<<m[i][j];
//            }
//        }
//        cout<<endl;
        memset(dp,0,sizeof(dp));
        int res=1;
        for(int i=0;i<n;i++){
            for(int j=n-1;j>=0;j--){
                //cout<<i<<"	"<<j<<"	";
                //cout<<1111111<<endl;
                if(i==0||j==n-1){
                    dp[i][j]=1;
                    //cout<<"is "<<dp[i][j]<<endl;
                    continue;
                }
                int x=i,y=j;
                while(x>=0&&y<=n-1&&m[x][j]==m[i][y]){
                    x--;
                    y++;
                }
                y=y-j;
                if(y>dp[i-1][j+1]){
                    dp[i][j]=dp[i-1][j+1]+1;
                }
                else{
                    dp[i][j]=y;
                }
                //cout<<"is  "<<dp[i][j]<<endl;
                res=max(res,dp[i][j]);
            }
        }
        printf("%d
",res);
    }
}
原文地址:https://www.cnblogs.com/liuzhanshan/p/6562029.html