UVA10617-Again Palindrome
UVA10617-Again Palindrome
题意
T组数据,每次给出一个字符串s,问它有多少个回文序列
题解
根据子串的长度,如果已知长度为len-1的字符串中所含回文子序列的个数,那么可以推出长度为len的字符串中回文子序列的个数。
dp[l][r]表示在区间[l,r]中的回文子序列数,该字符串长度为r-l+1。那么如果\(s[l] \neq s[r]\),dp[l][r]=dp[l][r-1]+dp[l+1][r]-dp[l+1][r-1]。如果\(s[l]=s[r]\),dp[l][r]=dp[l][r-1]+dp[l+1][r]-dp[l+1][r-1]+1(s[l]和s[r]组成的回文子序列)+dp[l+1][r-1](以s[l]和s[r]作为两端的回文子序列),化简为dp[l][r]=dp[l][r-1]+dp[l+1][r]+1。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=65;
char s[N];
ll dp[N][N];
ll ans;
int t,n;
int main(){
scanf("%d",&t);
while(t--){
scanf("%s",s+1);
n=strlen(s+1);
for(int i=1;i<=n;i++) dp[i][i]=1;
for(int len=2;len<=n;len++){
for(int l=1;l<=n;l++){
int r=l+len-1;
if(s[l]==s[r]){
dp[l][r]=dp[l][r-1]+dp[l+1][r]+1;
}else{
dp[l][r]=dp[l][r-1]+dp[l+1][r];
if(l+1<=r-1) dp[l][r]-=dp[l+1][r-1];
}
}
}
printf("%lld\n",dp[1][n]);
}
return 0;
}

浙公网安备 33010602011771号