解题思路:求一个字符串中的回文子串个数。要注意因为是要取余的,所以dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]可能是负数,所以还要+mod来确保它是正数。
以下摘自https://blog.youkuaiyun.com/u014492306/article/details/45243649
用dp[i][j]表示这一段里有多少个回文串,那首先dp[i][j]=dp[i+1][j]+dp[i][j-1],但是dp[i+1][j]和dp[i][j-1]可能有公共部分,
所以要减去dp[i+1][j-1]。
如果str[i]==str[j]的话,还要加上dp[i+1][j-1]+1,因为首尾是可以组成一个回文子串的,而且首尾可以与中间任何一个回文子串组成新的回文子串 。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mod 10007
using namespace std;
char s[1005];
int dp[1005][1005];
void solve()
{
int l=strlen(s);
memset(dp,0,sizeof(dp));
for(int i=0;i<l;i++) dp[i][i]=1;
for(int d=1;d<l;d++)
{
for(int i=0;i+d<l;i++)
{
int j=i+d;
if(s[i]==s[j])
dp[i][j]+=dp[i+1][j-1]+1;
dp[i][j]%=mod;
dp[i][j]+=(dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]+mod);
dp[i][j]%=mod;
}
}
}
int main()
{
//freopen("t.txt","r",stdin);
int T,cnt=0;
scanf("%d",&T);
while(T--)
{
cnt++;
scanf("%s",s);
solve();
printf("Case %d: %d\n",cnt,dp[0][strlen(s)-1]);
}
return 0;
}