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; }