题意:
给出t个字符串,输出每个字符串包含的回文子串数量。
解法:
利用dp和容斥。设dp[i][j]为i到j的回文子串的数量,则有dp[i][j]=dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1](即i到j的回文子串=i+1到j的回文子串+i到j-1的回文子串-重复的回文子串)。注意若是s[i]==s[j],则i+1到j-1中的所有回文子串都可以和i和j一起组成一个新的回文子串,i和j也可以组成一个回文子串,此时dp[i][j]+=dp[i+1][j-1]+1。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<stdlib.h>
#include<cstring>
#include<set>
using namespace std;
int n,t;
long long dp[60+5][60+5];
char s[60+5];
int main()
{
scanf("%d",&t);
while(t--){
scanf("%s",s+1);
n=strlen(s+1);
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)dp[i][i]=1;
for(int i=n-1;i>=1;i--){
for(int j=i+1;j<=n;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-1]+1;
}
}
printf("%lld\n",dp[1][n]);
}
return 0;
}