使用动态规划求解最长回文子串
1.动态规划的三要素
1)状态容器
状态容器可以用二维数组或一维数组存储。本题应使用二维数组进行状态容器的实现。
2)初始状态
3)状态转移方程
2.具体解法
1)首先设置一个二维int数组db用来存储状态,于是db[i][j]表示从i位置到j位置的子串是否为回文串。
2)求出状态转移方程。
对于最长回文字符串abcba来说:
a | b | c | b | a |
---|---|---|---|---|
i | i+1 | j-1 | j |
从上图看出当abcba为回文串时,bcb也为回文串,于是可以想到:
当db[i][j]为最长回文子串时,一定有db[i+1][j-1]为回文串。即当0<j-i<=2时
状态转移方程为:
db[i][j] = db[i+1][j-1]
当j-i=0时初始状态为:
db[i][j] = 1
用代码表示如下:
//初始状态赋值
for(i = 0;i < len;++i)
dp[i][i] = 1;
//其它状态赋值
for(j = 1;j < len;++j){
for(i = 0;i < len-1&&i<j;i++)
{
if(s[i] != s[j])
dp[i][j] = 0;
else if(j-i<=2)
dp[i][j] = 1;
else
dp[i][j] = dp[i+1][j-1];
}
}
以上就求出了dp数组中的所有状态值。
设置两个变量start(表示最长回文子串的开始位置),max(表示最长回文子串的长度)。
//设置max和start的初始值
int max = 1,start = 0;
接下来我们所需要的就是根据状态值来求出最长的回文子串。
伪代码如下:
if(字符串i到j为回文串 && 该回文串长度比上一次回文串长度更大)
{
更新start的开始位置;
更新max的值;
}
翻译成c++代码如下:
if(dp[i][j]