【HDU】4632 Palindrome subsequence (DP)

来源:互联网 发布:js 非严格模式 编辑:程序博客网 时间:2024/05/16 17:37

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 <A, B, D> is a subsequence of <A, B, C, D, E, F>.
(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 = <Sx1, Sx2, ..., Sxk> and Y = <Sy1, Sy2, ..., Syk> , if there exist an integer i (1<=i<=k) such that xi != yi, the subsequence X and Y should be consider different even if Sxi = Syi. 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
4 a aaaaa goodafternooneveryone welcometoooxxourproblems
 

 

Sample Output
Case 1: 1 Case 2: 31 Case 3: 421 Case 4: 960

    1. 经过观察,发现性质:对于str[i]==str[j]  && i<j,那么所有首位为a、末位为b、且满足
(i<a && a<=b && b<j)的回文序列,一定可以在两端加上str[i]和str[j]后,构成一个新的回
文序列,并且这个回文序列的首元素为str[i]、尾元素为str[j];
    2. 维护两个数组,ans[N]和cnt[N],ans[i]表示以元素i为首位的回文序列的数量、cnt[i]表
示以元素i结尾的回文序列的数量;
    3. 逆向遍历str(正向也行),初始化ans[i]=1,cnt[i]=1,代表自己单独为一个序列;同
时用指针j,从str尾向前遍历while(i<j),当str[i]==str[j]的时候,进行如下操作:
        (1)ans[i]++,cnt[j]++,(代表i和j单独构成一个序列);
        (2)统计sum=所有cnt[k]的和,k满足(i<k && k<j),然后ans[i]+=sum,cnt[i]+=sum;
        
    最后统计所有的ans的SUM,既为所求。
    对于3.(2),需要用树状数组或者线段树快速求和。

#include <stdio.h>#include <algorithm>#include <string.h>#include <iostream>#include <map>#include <vector>#include <queue>#include <set>#include <string>#include <math.h>using namespace std;const int MOD = 10007;int dp[1100][1100];int n;char str[1100];int solve(int l,int r){    if(l > r)return 0;    if(l == r)return dp[l][r] = 1;    if(dp[l][r] != -1)return dp[l][r];    if(r == l+1)    {        if(str[l] == str[r])            return dp[l][r] = 3;        else return dp[l][r] = 2;    }    dp[l][r] = solve(l+1,r)+solve(l,r-1);    if(dp[l][r] >= MOD)dp[l][r]-=MOD;    if(str[l]==str[r])    {        dp[l][r] ++;        if(dp[l][r] >= MOD)dp[l][r]-=MOD;    }    else    {        dp[l][r] -= solve(l+1,r-1);        if(dp[l][r]<0)dp[l][r] += MOD;    }    return dp[l][r];}int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int T;    int iCase = 0;    scanf("%d",&T);    while(T--)    {        iCase++;        memset(dp,-1,sizeof(dp));        scanf("%s",str);        n = strlen(str);        printf("Case %d: %d\n",iCase,solve(0,n-1));    }    return 0;}

—————————————————————————————————

本文原创自Sliencecsdn技术博客。

本博客所有原创文章请以链接形式注明出处。

欢迎关注本技术博客,本博客的文章会不定期更新。


大多数人想要改造这个世界,但却罕有人想改造自己。

世上没有绝望的处境,只有对处境绝望的人。

                                              ————By slience

—————————————————————————————————


0 0
原创粉丝点击