题意(事实上未曾找到相关题目):
给定一字符串,求它的回文子序列个数。内容相同位置不同的子序列算不同的子序列。
例如字符串aba中,回文子序列为"a", "a", "aa", "b", "aba",共5个。
思路:
对于任意字符串,如果头尾字符不相等,则字符串的回文子序列个数就等于去掉头的字符串的回文子序列个数+去掉尾的字符串的回文子序列个数-去掉头尾的字符串的回文子序列个数;如果头尾字符相等,则字符串的回文子序列个数就等于去掉头的字符串的回文子序列个数+去掉尾的字符串的回文子序列个数+1。
用dp[i][j]表示第i到第j个字符间的最长回文子序列的长度(i<=j),则状态转移方程为:
dp[i][j]=dp[i+1][j] + dp[i][j-1] - dp[i+1][j-1] , if(s[i]!=s[j])
dp[i][j]=dp[i+1][j] + dp[i][j-1] +1 , if (s[i]==s[j])
代码:
#include <iostream>
using namespace std;
int dp[200][200];
string str;
int solve(){
int l=str.length();
for(int j=0;j<l;++j){
dp[j][j]=1;
for(int i=j-1;i>=0;--i){
if(str[i]==str[j]) dp[i][j]=dp[i+1][j]+dp[i][j-1]+1;
else dp[i][j]=dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1];
}
}
return dp[0][l-1];
}
int main(){
while(cin>>str){
cout<<solve()<<endl;
}
return 0;
}