HDU 2859 Phalanx

** 题目链接 ** : [kuangbin带你飞]专题十二 基础DP1 Q - Phalanx

题意

给定矩阵,求符合对称矩阵的最大子矩阵的宽度。 这里的对称矩阵是以 ** 左下至右上 ** 为轴的。

思路

一个n*n的对称矩阵,对角线上的元素上方与右方的相同元素数量,一定比其左下方少1。
例如
123
412
541
上面矩阵对角线上
3的相同元素数量为1(包括自身),
1为2,5为3
所以可以把每个矩阵视为其所在矩阵的对角线上的元素,如果其相同元素大于右上方,则它当前所在对称矩阵的最大宽度为右上方的最大宽度加1

代码

1. 第一次ac

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;

const int N = 1009;
int dp[N][N];
char s[N][N];

int main()
{
    int n;
    while(cin>>n && n)
    {
        memset(dp, 0, sizeof(dp));
        for(int i=0; i<n; i++)
        {
            cin>>s[i];
            dp[0][i] = 1;
        }
        int ans = 1;
        for(int i=1; i<n; i++)
        {
            for(int j=n-1; j>=0; j--)
            {
                int x = i-1, y = j+1;
                int num = 1;
                while(x>=0 && x<n && y>=0 && y<n && s[x][j] == s[i][y])
                {
                    num++;
                    x--;
                    y++;
                }
                if(num > dp[i-1][j+1])
                    dp[i][j] = dp[i-1][j+1]+1;
                else
                    dp[i][j] = num;
                ans = max(dp[i][j], ans);
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

2. 第二次ac,发现dp数组可以从二维降至一维

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;

const int N = 1009;
int dp[N];
char s[N][N];

int main()
{
    int n;
    while(~scanf("%d", &n) && n)
    {
        memset(dp, 0, sizeof(dp));
        for(int i=0; i<n; i++)
            scanf("%s", s[i]);
        int ans = 1;
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                int x = i-1, y = j+1;
                int num = 1;
                while(x>=0 && x<n && y>=0 && y<n && s[x][j] == s[i][y])
                {
                    num++;
                    x--;
                    y++;
                }
                if(num > dp[j+1])
                    dp[j] = dp[j+1]+1;
                else
                    dp[j] = num;
                ans = max(dp[j], ans);
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}