给定某个字符串,找到其长度最大的子序列,该子序列无论正读还是反读都一样,例如abcdcba ofo.......
现给定字符串 acccbda 求其最长回文子序列的长度。
可以看出满足要求的最优解是 accca 即长度为5
动态规划的本质是找最优子结构的解,然后写状态转移方程。
思路是先比较某个字串的首尾看是否相同,若相同,则dp[i][j]=dp[i-1][j-1]+2,此处dp[i][j]表示以下标i为开始,以j结束的子序列的最优解 例如 abrcsa 因为首位相等都为a,则最优解在去掉首尾的子序列里再找,并且加上首尾的长度。
若首尾不相等 :acdbce acdbce 则比较蓝色与红色序列的最优解,当然我们的递推寻找从长度为1的子序列开始。
下面给出代码
#include<bits/stdc++.h>
using namespace std;
int dp[100][100];
int temp;
int maxline(char *str,int len)
{
for(int i=0;i<len;i++)
dp[i][i]=1; ///设置所有长度为1的子序列的最优解为1
for(int i=1;i<len;i++)
{
temp=0;
for(int j=0;i+j<len;j++)
{
if(str[j]==str[i+j])///首尾相等的情况
temp=dp[j+1][i+j-1]+2;
else///不相等
temp=max(dp[j][i+j-1],dp[j+1][i+j]);
dp[j][i+j]=temp;///j开始 i+j结束的子序列的最优解
}
}
return dp[0][len-1];///返回字符串的最优解
}
int main()
{
char str[50];
gets(str);
int len=strlen(str);
int res=maxline(str,len);
printf("%d\n",res);
return 0;
}
下面是运行结果