uva 10069 Distinct Subsequences(DP + 大数相加)

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 = x1x2xm, another sequence Z = z1z2zk 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

2
babgbag
bag
rabbbit
rabbit

Sample Output

5

3  


#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;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值