HDU - 2859 Phalanx

input:
3 abx cyb zca 4 zaba cbab abbc cacq 0
output:
3 3
题目大意:
n×n的矩阵,找到最大的子对称阵,但是他是左下角到右上角这条轴对称。
分析:
dp。dp[i][j]=从i,j坐标开始的轴的最大对称阵大小。其实想法很简单,但是可能会怕超时,会忽略。要求 dp[i][j]的最大子对称阵大小,需要知道dp[i-1][j+1]的子对称阵大小,因为dp[i-1][j+1]保证了 (i-1,j+1)->(i-1+dp[i-1][[j+1]-1,j+1+dp[i-1][j+1]-1)都是对称的,所以我们可以从(i,j)这个点开始分别 向上和向左进行字符串匹配,如果一边先到边界或者不相等匹配结束,将i-匹配结束的那个竖直方向的行数记 为t1,比较t1跟dp[i-1][j+1]+1,如果t1>=dp[i-1][j+1]+1,更新最大值,否则,dp[i][j]=t1。
code:
#define frp
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = 0x3f3f3f3f;
const ll inf = 0x7fffff;
const int maxn = 1000;
const int MAXN = 1050;
string a[MAXN];
int dp[MAXN][MAXN];
int n;
void solve() {
while (cin >> n && n) {
int ans = 1;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i == 0 || j == n - 1) {
dp[i][j] = 1;
// cout << "i = " << i << " j = " << j << ":" << dp[i][j] << " ";
continue;
}
int t1 = i, t2 = j;
while (t1 >= 0 && t2 < n && a[t1][j] == a[i][t2]) {
t1--;
t2++;
}
t1 = i - t1;
if (t1 >= dp[i - 1][j + 1] + 1) {
dp[i][j] = dp[i - 1][j + 1] + 1;
ans = max(ans, dp[i][j]);
} else {
dp[i][j] = t1;
}
// cout << "i = " << i << " j = " << j << ":" << dp[i][j] << " ";
}
// cout << endl;
}
cout << ans << endl;
memset(dp, 0, sizeof(dp));
}
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#ifdef frp
freopen("D:\\coding\\c_coding\\in.txt", "r", stdin);
// freopen("D:\\coding\\c_coding\\out.txt", "w", stdout);
#endif
solve();
return 0;
}

浙公网安备 33010602011771号