PAT C 语言入门题目-7-64 最长对称子串 (25 分)四种方法求解(暴力枚举+动态规划+中心扩展+manacher算法(马拉车))

7-64 最长对称子串 (25 分)

对给定的字符串,本题要求你输出最长对称子串的长度。例如,给定Is PAT&TAP symmetric?,最长对称子串为s PAT&TAP s,于是你应该输出11。

输入格式:

输入在一行中给出长度不超过1000的非空字符串。

输出格式:

在一行中输出最长对称子串的长度。

输入样例:

Is PAT&TAP symmetric?

输出样例:

11

 四种方法链接

以下仅动态规划法:

令 dp[i][j] 表示 S[i] 至 S[j] 所表示的子串是否是回文子串,是则为 1,不是则为 0。这样根据 S[i] 是否等于 S[j] ,可以把转移情况分为两类:

 若 S[i] == S[j],那么只要 S[i+1] 至 S[j-1] 是回文子串,S[i] 至 S[j] 就是回文子串;如果S[i+1] 至 S[j-1] 不是回文子串,则 S[i] 至 S[j] 也不是回文子串。
 若 S[i] != S[j],那么 S[i] 至 S[j] 一定不是回文子串。    
  由此可以写出状态转移方程:

          dp[i][j]={dp[i+1][j−1],S[i]==S[j]0,S[i]!=S[j]dp[i][j]={dp[i+1][j−1],S[i]==S[j]0,S[i]!=S[j]

  边界:dp[i][i]=1,dp[i][i+1] = (S[i] == S[i+1]) ? 1 : 0。

  根据递推写法从边界出发的原理,注意到边界表示的是长度为 1 和 2 的子串,且每次转移时都对子串的长度减了 1,因此不妨考虑按子串的长度和子串的初始位置进行枚举,即第一遍将长度为 3 的子串的 dp 值全部求出,第二遍通过第一遍结果计算出长度为 4 的子串的 dp 值 ……

 算法时间复杂度为O(N ^ 2)。


#include 
#include 
#include 
#include 
#include 
#include 
 
#define maxn 1010
char S[maxn];
int dp[maxn][maxn];                 
 
int main() {
    gets(S);                        // 输入整行字符 
    int len=strlen(S), ans=1;        // ans 记录最长回文子串长度 
    int i, j, L;        
    // 边界 
    for(i=0; i

 

你可能感兴趣的:(C,动态规划)