1. 程式人生 > >動規-HDU-2859

動規-HDU-2859

acm std cnblogs name iostream log 動規 cout str

http://acm.hdu.edu.cn/showproblem.php?pid=2859

Phalanx

給定一個n*m的字符矩陣,求最大以副對角線對稱的子方陣行數。

解題報告

思路

對於給定字符矩陣M:

記以元素M[i][j]為左下角的最大副對角線對稱子方陣行數為dp[i][j]。

假設已經求得dp[i-1][j+1],欲求dp[i][j],則需要以dp[i-1][j+1]為上界,判斷從M[i][j]為左下角開始的M[i][k]與M[k][j]有多少個連續相同即可。

那麽就可以兩層循環遍歷每個元素,對於每個元素按上述方法求得dp[i][j],取其中的最大值即為解。

(這種O(n^3)的做法能過也多虧給的時間限制夠寬松...)

代碼

#include <algorithm>
#include <iostream>
#include <string>

using namespace std;

const int maxn = 1003;

string str[maxn];
int dp[maxn][maxn];
int n;
int ans;

int Check(int x, int y) {
    int tx = x, ty = y, len = dp[x-1][y+1];
    int cnt = 0;
    for (int i = 0; i < len; i++) {
        tx
--; ty++; if (tx < 0 || ty >= n) break; if (str[tx][y] != str[x][ty]) break; cnt++; } return cnt; } int main() { ios::sync_with_stdio(false); cin.tie(0); while (cin >> n, n) { for (int i = 0; i < n; i++) { cin >> str[i];
for (int j = 0; j < n; j++) { dp[i][j] = 1; } } ans = 1; for (int i = 1; i < n; i++) { for (int j = 0; j < n - 1; j++) { dp[i][j] = Check(i, j) + 1; ans = max(ans, dp[i][j]); } } cout << ans << endl; } return 0; }

--(完)--

動規-HDU-2859