標籤:
http://acm.hdu.edu.cn/showproblem.php?pid=5282
Problem DescriptionXuejiejie 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.
InputIn 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.
OutputFor 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
2abaaab
Sample Output
12
/**hdu5282 最長公用子序列的變形題目大意:給定兩個字串,求二者的最長公用子序列,在a中出現過的,有多少是b的子序列解題思路:來自官方題解。 首先我們用O(n2)的動態規划算法處理出dp數組,dp[i][j]表示X串的前i個字元和Y 串的前j個字元的最長公用子序列的長度,在這個基礎上我們再進行一個動態規劃。 用f[i][j]表示在X串的前i個字元中,有多少個長度為dp[i][j]的子序列在Y的前j個 字元中也出現了。轉移:若dp[i?1][j]==dp[i][j],則f[i][j]+=f[i?1][j],表示i 這個字元不選;再考慮選i這個字元,找到Y串前j個字元中最靠後的與X[i]匹配的字 符的位置,設為p,若dp[i?1][p?1]+1==dp[i][j],則f[i][j]+=f[i?1][p?1]。最終 的答案即為f[n][m]。複雜度O(n2)。*/#include <stdio.h>#include <string.h>#include <algorithm>#include <iostream>using namespace std;typedef long long LL;const LL mod=1e9+7;const int maxn=1005;int dp[maxn][maxn],n,m,wei[maxn][maxn];char a[maxn],b[maxn];LL f[maxn][maxn];int main(){ int T; scanf("%d",&T); while(T--) { scanf("%s%s",a,b); n=strlen(a); m=strlen(b); memset(dp,0,sizeof(dp)); for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { dp[i+1][j+1]=max(dp[i+1][j],dp[i][j+1]); if(a[i]==b[j]) dp[i+1][j+1]=max(dp[i][j]+1,dp[i+1][j+1]); } } memset(wei,0,sizeof(wei)); for(int i=1;i<=m;i++) { for(int j=0;j<26;j++) { wei[i][j]=wei[i-1][j]; } wei[i][b[i-1]-'a']=i; } memset(f,0,sizeof(f)); for(int i=0;i<=n;i++) { for(int j=0;j<=m;j++) { if(dp[i][j]==0) { f[i][j]=1; continue; } if(dp[i-1][j]==dp[i][j]) { f[i][j]=(f[i][j]+f[i-1][j])%mod; } int p=wei[j][a[i-1]-'a']; if(p) { if(dp[i-1][p-1]+1==dp[i][j]) { f[i][j]=(f[i][j]+f[i-1][p-1])%mod; } } } } printf("%I64d\n",f[n][m]); } return 0;}
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
hdu5282 最長公用子序列的變形