Given a string, you are supposed to output the length of the longest symmetric sub-string. For example, givenIs PAT&TAP symmetric?
, the longest symmetric sub-string iss PAT&TAP s
, hence you must output11
.
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
- 思路 1:动态规划:最长回文子串
判断任意一段子串sub: [i, j]
可以缩减为
子问题1:s[i] == s[j] ?
子问题2:sub: [i+1, j-1] 是回文串否?
若都成立,则sub[i, j]是回文子串
可以看出,每次迭代,子串长度L+2(i 和 j)
当L为奇数时:边界为sub[i, i](即L == 1
),每个字符自身就是一个回文子串
当L为偶数时:边界为sub[i, i+1](即L == 2
),若两个相邻字符相同,则子串sub[i, i+1]是回文串,否则不是
由此可得到状态转移方程:
dp[i][j] =
如果 s[i] == s[j] and dp[i+1][j-1] == 1 : 则是回文串 ,= 1
先求出边界L=1和L=2,再枚举L 从 3 到 字符串长度,每轮遍历求出对应子串的dp[i][i+L-1]
如果本次迭代发现合格的回文子串(即:有dp[i][j] 更新为 1
)则更新长度Max
- code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1010;
int dp[maxn][maxn];
int main(){
string s;
getline(cin, s);
int Max = 1;
for(int i = 0; i < s.size(); ++i){
dp[i][i] = 1;
if(i < s.size() - 1 && s[i] == s[i+1]){
dp[i][i+1] = 1;
Max = 2;
}
}
for(int L = 3; L <= s.size(); ++L){ //Wrong 1: L <= s.size()!!
for(int i = 0; i < s.size() - L + 1; ++i){
int j = i + L - 1;
if(s[i] == s[j] && dp[i+1][j-1] == 1){
dp[i][j] = 1;
Max = L;
}
}
}
printf("%d", Max);
return 0;
}