PTA (Advanced Level)1040 Longest Symmetric String
1040 Longest Symmetric String (25 分)
Given a string, you are supposed to output the length of the longest symmetric sub-string. For example, given Is PAT&TAP symmetric?
, the longest symmetric sub-string is s PAT&TAP s
, hence you must output 11
.
Input Specification:
Each input file contains one test case which gives a non-empty string of length no more than 1000.
Output Specification:
For each test case, simply print the maximum length in a line.
Sample Input:
Is PAT&TAP symmetric?
Sample Output:
11
解題思路:
本題給出一行字元這裡記為text,要求輸出改行字元中最大回文串的長度。這裡採用動態規劃做法,用布林陣列dp[ bg ][ ed ]記錄下標 bg ~ ed 組成的子串是否為迴文串。設長度為1的字串為迴文串,在初始化dp陣列是可以將長度為1與長度為2的字串是否為迴文串都標記完成。
對任意一個字串都有兩種情況:
1、是迴文串,其對應dp為true;
2、不是迴文串,其對應dp為false;
判斷一個字串是否為迴文串只需要判斷其首尾字元是否相等與其除首尾字元外的子串是否為迴文串即可,這就轉化為了求dp[bg + 1][ ed - 1],和判斷text[ bg ]與text[ ed ]是否相等的問題。
動態轉移方程:dp[bg][ed] = 1(text[ bg ] == text[ ed ],dp[bg + 1][ ed - 1 ] == true)
之後只要遍歷所有子串長度,遍歷所有起始下標,並計根據其實下標與子串長度計算出末尾下標,根據動態轉移方程即可求出答案。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1e3+100; 4 bool dp[maxn][maxn] = {false}; //預設所有字串都不是迴文 5 string text; //text為出入的字串 6 int main() 7 { 8 getline(cin, text); 9 int len = text.size(); 10 int ans = 0; 11 for(int i = 0; i < len; i++){ 12 dp[i][i] = true; //標記長度為1的字串為迴文串 13 ans = 1; //最大回文串長度為1 14 if(i < len - 1 && text[i] == text[i + 1]){ //如果有兩個連續字元 15 //(長度為2的迴文串只有兩個連續字元這種情況) 16 dp[i][i + 1] = 1; //標記其組成的字串為迴文串 17 ans = 2; //最大回文串長度為2 18 } 19 } 20 for(int tempLen = 3; tempLen <= len; tempLen++){ //遍歷子串長度長度從3 ~ len的 21 for(int bg = 0; bg + tempLen - 1 < len; bg++){ 22 //遍歷起始位置,末尾下標為起始位置+當前子串長度-1,末尾下標不能達到給定字串末位 23 int ed = bg + tempLen - 1; 24 if(text[bg] == text[ed] && dp[bg + 1][ed - 1] == true){ //動態轉移方程 25 dp[bg][ed] = 1; 26 ans = tempLen; //記錄答案 27 } 28 } 29 } 30 printf("%d\n", ans); 31 return 0; 32 }