对给定的字符串,本题要求你输出最长对称子串的长度。例如,给定Is PAT&TAP symmetric?,最长对称子串为s PAT&TAP s,于是你应该输出11。
输入格式:
输入在一行中给出长度不超过1000的非空字符串。
输出格式:
在一行中输出最长对称子串的长度。
输入样例:
Is PAT&TAP symmetric?
输出样例:
11
**思路:**使用动态规划算法,当然也有目前最优秀的manacher算法,不过最近在学动态规划,那么这道题就用动态规划算做。
dp[i][j]表示字符串s从i到j之间的子串是否为回文字符串,1表示是,0表示不是。如果s[i]==s[j]并且dp[i+1][j-1]为1,则i~j必定为回文字符串。若s[i] != s[j]则必定不是回文字符串。边界为d[i][i] = 1,dp[i][i+1] = (s[i]==s[i+1]) ? 1 : 0。
状态转移方程
d
p
[
i
]
[
j
]
=
{
d
p
[
i
+
1
]
[
j
−
1
]
,
s
[
i
]
=
=
s
[
j
]
0
,
s
[
i
]
!
=
s
[
j
]
dp[i][j] = \left\{ \begin{aligned} dp[i+1][j-1],s[i]==s[j]\\ 0 ,s[i]!=s[j] \end{aligned} \right.
dp[i][j]={dp[i+1][j−1],s[i]==s[j]0,s[i]!=s[j]
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const int MAXN = 10000;
int dp[MAXN][MAXN]={0};
int main(){
string st;
getline(cin,st);
int ans = 1;
//边界
for(int i = 0; i < st.size(); i++){
dp[i][i] = 1;
if(i < st.size()-1 && st[i] == st[i+1]){
dp[i][i+1] = (st[i] == st[i+1]) ? 1 : 0;
ans =2;
}
}
for(int L = 3; L <= st.length(); L++){
for(int i = 0; i+L-1 < st.length(); i++){
int j = i+L-1;
if(st[i] == st[j] && dp[i+1][j-1]==1){
dp[i][j]=1;
ans = L;
}
}
}
cout << ans;
return 0;
}