题目链接:[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;
}