HDU 4632 回文串(区间dp)

比眉伴天荒 2024-02-17 19:34 125阅读 0赞

Palindrome subsequence

Problem Description

In mathematics, a subsequence is a sequence that can be derived from another sequence by deleting some elements without changing the order of the remaining elements. For example, the sequence is a subsequence of .
(http://en.wikipedia.org/wiki/Subsequence)

Given a string S, your task is to find out how many different subsequence of S is palindrome. Note that for any two subsequence X = and Y = , if there exist an integer i (1<=i<=k) such that xi != yi, the subsequence X and Y should be consider different even if S xi = S yi. Also two subsequences with different length should be considered different.

Input

The first line contains only one integer T (T<=50), which is the number of test cases. Each test case contains a string S, the length of S is not greater than 1000 and only contains lowercase letters.

Output

For each test case, output the case number first, then output the number of different subsequence of the given string, the answer should be module 10007.

Sample Input

  1. 4
  2. a
  3. aaaaa
  4. goodafternooneveryone
  5. welcometoooxxourproblems

Sample Output

  1. Case 1: 1
  2. Case 2: 31
  3. Case 3: 421
  4. Case 4: 960

分析:区间dp问题,状态方程:dp(i,j)=(dp(i+1,j)+dp(i,j-1)-dp(i+1,j-1)+mod)%mod,因为()内可能小于0,故加上mod。表示从I到j的回文串个数

if(s[i]==s[j]),则 还有加上1+dp(i+1,j-1);

AC代码:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5. const int maxn=1000+10;
  6. const int mod=10007;
  7. char s[maxn];
  8. int dp[maxn][maxn];
  9. int main(){
  10. int T;
  11. scanf("%d",&T);
  12. int count1=0;
  13. while(T--){
  14. scanf("%s",s+1);
  15. int l=strlen(s+1);
  16. memset(dp,0,sizeof(dp));
  17. for(int len=1;len<=l;len++) //长度
  18. for(int i=1;i<=l-len+1;i++){ //起点位置
  19. int j=i+len-1; //终点位置
  20. dp[i][j]=(dp[i][j-1]+dp[i+1][j]-dp[i+1][j-1] + mod)%mod;
  21. if(s[i]==s[j])
  22. dp[i][j]=(dp[i][j]+1+dp[i+1][j-1])%mod; //首尾是一个回文串,并且中间任何一个回文串和首尾组成的仍是一个回文串
  23. }
  24. printf("Case %d: ",++count1);
  25. printf("%d\n",dp[1][l]);
  26. }
  27. return 0;
  28. }

发表评论

表情:
评论列表 (有 0 条评论,125人围观)

还没有评论,来说两句吧...

相关阅读

    相关

    /Description 有一行文字,全部是汉字,不超过一百个汉字,请判断这句话是否是回文。若是回文串,输出Yes,不是则输出No。 Input 测试数据有多组,每组单

    相关 516 最长子序列(区间dp

    1. 问题描述: 给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。