1. 程式人生 > >【HDU - 2859 】Phalanx (dp 最大對稱子圖)

【HDU - 2859 】Phalanx (dp 最大對稱子圖)

Phalanx

先搬翻譯

Descriptions:

給你一個矩陣,只由小寫或大寫字母構成。求出它的最大對稱子矩陣的邊長。 其中對稱矩陣是一個k*k的矩陣,它的元素關於從左下角到右上角的對角線對稱。
例如下面這個3* 3的矩陣是對稱矩陣:
cbx
cpb
zcc

Input

多組資料。每一組第一行是一個 n (0<n<=1000),下面是n行,每一行有n個字母,中間沒有空格。資料以n=0結束。

Output

每組資料輸出最大的對稱矩陣的邊長。

Sample Input

3
abx
cyb
zca
4
zaba
cbab
abbc
cacq
0

Sample Output

3
3

題目連結:

https://vjudge.net/problem/HDU-2859

 

dp[i][j] 表明的是你在第i行第j列的時候的最大對稱矩陣

dp[i][j]可以在滿足條件的情況下轉移到dp[i-1][j+1]的狀態上來

 

AC程式碼

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#define Mod 1000000007
#define eps 1e-6
#define ll long long
#define INF 0x3f3f3f3f
#define MEM(x, y) memset(x, y, sizeof(x))
#define Maxn 1000+10
using namespace std;
int n,len,ans;
char s[Maxn][Maxn];//存影象
int dp[Maxn][Maxn];//在第i行第j列的時候的最大對稱矩陣
int main()
{
    while(cin>>n&&n!=0)
    {
        ans=1;//初始化
        MEM(s,0);
        MEM(dp,0);
        for(int i=0; i<n; i++)//存圖形
            for(int j=0; j<n; j++)
                cin>>s[i][j];
        for(int i=0; i<n; i++)//開始一個一個為頂點開始搜尋
        {
            for(int j=n-1; j>=0; j--)
            {
                dp[i][j]=1;//每一個字母 其本身就是一個對稱矩陣
                if(i==0||j==n-1)//邊緣部分不用管
                    continue;
                int t=dp[i-1][j+1];//其右上角那個點是t階
                //檢測這個點是否能超過右上角的對稱矩陣
                for(int k=1; k<=t; k++)
                {
                    if(s[i-k][j]==s[i][k+j])
                        dp[i][j]++;
                    else
                        break;
                }
                ans=max(ans,dp[i][j]);
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

&n