Problem E
Distinct Subsequences
Input: standard input
Output: standard output
A subsequence of a given sequence is just the given sequence with some elements (possibly none) left out. Formally, given a sequence X = x1x2�xm, another sequence Z = z1z2�zk is a subsequence of X if there exists a strictly increasing sequence <i1, i2, �, ik> of indices of X such that for all j = 1, 2, �, k, we have xij = zj. For example, Z = bcdb is a subsequence of X = abcbdab with corresponding index sequence < 2, 3, 5, 7 >.
In this problem your job is to write a program that counts the number of occurrences of Z in X as a subsequence such that each has a distinct index sequence.
Input
The first line of the input contains an integer N indicating the number of test cases to follow.
The first line of each test case contains a string X, composed entirely of lowercase alphabetic characters and having length no greater than 10,000. The second line contains another string Z having length no greater than 100 and also composed of only lowercase alphabetic characters. Be assured that neither Z nor any prefix or suffix of Z will have more than 10100 distinct occurrences in X as a subsequence.
Output
For each test case in the input output the number of distinct occurrences of Z in X as a subsequence. Output for each input set must be on a separate line.
Sample Input
2babgbag
bag
rabbbit
rabbit
Sample Output
53
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 110;
string dp[maxn][maxn*100];
string s1 , s2;
void reverse(string &ans,int ct){
for(int i=0;i<ct/2;i++){
swap(ans[i],ans[ct-1-i]);
}
}
string add(string a,string b){
int la=a.length(),lb=b.length();
int c=0,ct;
int d[maxn*100];
string ans="";
if(la>lb) swap(a,b),swap(la,lb);
reverse(a,la),reverse(b,lb);
for(int i=0;i<la;i++){
d[i]=a[i]-'0'+b[i]-'0'+c;
c=d[i]/10;
d[i]%=10;
}
for(int i=la;i<lb;i++){
d[i]=b[i]-'0'+c;
c=d[i]/10;
d[i]%=10;
}
if(c) d[lb]=c,ct=lb+1;
else ct=lb;
int i=ct-1;
//ȥǰµŒ0
while(i>=0&&d[i]==0) i--;
if(i<0) ans="0";
//
else for(;i>=0;i--) ans+=d[i]+'0';
return ans;
}
void initial(){
for(int i = 0;i < maxn;i++){
for(int j = 0;j < maxn;j++){
dp[i][j] = "0";
}
}
}
void computing(){
cin >> s1 >> s2;
if(s1.length() < s2.length()){
cout << 0 << endl;
return;
}
if(s1[0] == s2[0]){
dp[0][0] = "1";
}
for(int i = 1;i < s1.length();i++){
if(s1[i] == s2[0]){
dp[0][i] = add(dp[0][i-1],"1");
}else{
dp[0][i] = dp[0][i-1];
}
}
for(int i = 1;i < s2.length();i++){
for(int j = 1;j < s1.length();j++){
if(s1[j] == s2[i]){
dp[i][j] = add(dp[i][j-1],dp[i-1][j-1]);
}else{
dp[i][j] = dp[i][j-1];
}
}
}
/*for(int i = 0;i < s2.length();i++){
for(int j = 0;j < s1.length();j++){
cout << dp[i][j] << " " ;
}
cout << endl;
}*/
cout << dp[s2.length()-1][s1.length()-1] << endl;
}
int main(){
int t;
cin >> t;
while(t--){
initial();
computing();
}
return 0;
}