BestCoders

Senior's String

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 466    Accepted Submission(s): 183


Problem Description
Xuejiejie loves strings most. In order to win the favor of her, a young man has two strings  X Y  to Xuejiejie. Xuejiejie has never seen such beautiful strings! These days, she is very happy. But Xuejiejie is missish so much, in order to cover up her happiness, she asks the young man a question. In face of Xuejiejie, the young man is flustered. So he asks you for help.

The question is that :
Define the  L  as the length of the longest common subsequence of  X  and  Y .( The subsequence does not need to be continuous
in the string, and a string of length  L  has  2L  subsequences containing the empty string ). Now Xuejiejie comes up with all subsequences of length  L  of string  X , she wants to know the number of subsequences which is also the subsequence of string  Y .
 

Input
In the first line there is an integer  T , indicates the number of test cases.

In each case:

The first line contains string  X , a non-empty string consists of lowercase English letters.

The second line contains string  Y , a non-empty string consists of lowercase English letters.

1|X|,|Y|1000 |X|  means the length of  X .
 

Output
For each test case, output one integer which means the number of subsequences of length  L  of  X  which also is the subsequence of string  Y  modulo  109+7 .
 

Sample Input
   
   
   
   
2 a b aa ab
 

Sample Output
   
   
   
   
1 2
 

Source
BestCoder Round #47 ($)
 

Recommend
hujie

注:DP  d(i, j)表示最长公共子串长度  f(i, j)表示长度为d(i,j)的子串存在于Y中的数目

递推公式:很简单,选择一个条件,然后分析情况

这里选择取不取X(i)

I. if d(i, j) == d(i-1, j)   then f(i, j) += f(i-1, j);

II.if d(i, j) == d(i-1, p-1) + 1 | X(i)==Y(p) && p<=j   then f(i, j) += f(i-1, p-1).

Node: Initial Conditions--d(0,i) = d(i, 0) = 0, f(0, i) = f(0, i) = 1, f(i, j) = 0;

<pre name="code" class="cpp">#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

#define maxn 1005
#define MOD 1000000007

char s1[maxn], s2[maxn];
int d[maxn][maxn];
int f[maxn][maxn];
int pos[maxn][27];

void solve()
{
    int len1 = strlen(s1+1);
    int len2 = strlen(s2+1);
    memset(f, 0, sizeof(f));
    for(int i=0; i<=len2; i++)
    {
        d[0][i] = d[i][0] = 0;
        f[0][i] = f[i][0] = 1;
    }

    for(int i=1; i<=len1; i++)
        for(int j=1; j<=len2; j++)
            if(s1[i] == s2[j])
                d[i][j] = d[i-1][j-1] + 1;
            else
                d[i][j] = max(d[i-1][j], d[i][j-1]);

    memset(pos, 0, sizeof(pos));
    for(int i=1; i<=len2; i++)
    {
        for(int j=0; j<26; j++)
            pos[i][j] = pos[i-1][j];
        pos[i][s2[i]-'a'] = i;
    }

    f[0][0] = 1;
    for(int i=1; i<=len1; i++)
        for(int j=1; j<=len2; j++)
        {
            if(d[i][j] == 0)
            {
                f[i][j] = 1;
                continue;
            }
            if(d[i][j] == d[i-1][j])
                f[i][j] = (f[i][j] + f[i-1][j]) % MOD;
            int p = pos[j][s1[i]-'a'];
            if(p && d[i][j] == d[i-1][p-1] + 1)
                f[i][j] = (f[i][j] + f[i-1][p-1]) % MOD;
        }
        printf("%d\n", f[len1][len2]);
}

int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int T;
    cin>>T;
    while(T--)
    {
        scanf("%s", s1+1);
        scanf("%s", s2+1);
        solve();
    }
    return 0;
}


 
 

你可能感兴趣的:(ACM,best)