题目大意: 给你两个字符串Str,str,求Str的str子序列种数。
状态: dp[i][j] 表示前Str的前str的子序列种树。
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<math.h>
#include<functional>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 155;
const int inf = 1<<29;
const int mod = 100000000;
int n;
char Str[maxn*maxn],str[maxn];
struct node
{
int len,num[15];
}dp[3][maxn],One;
void add( node &a,node &b) //大数相加
{
int c = 0;
a.len = a.len > b.len?a.len:b.len;
for( int i = 0; i < a.len; i ++ ){
a.num[i] += b.num[i] + c;
c = a.num[i]/mod;
a.num[i] %= mod;
}
if( c )
a.num[a.len++] = c;
}
void GetDp() //核心代码
{
int Len = strlen(Str);
int len = strlen(str);
memset( dp,0,sizeof(dp) );
for( int i = 1; i <= Len; i ++ ){
for( int j = 1; j <= len; j ++ ){
dp[i%2][j] = dp[(i-1)%2][j];
if( Str[i-1] == str[j-1] ){
if( j == 1 )
add( dp[i%2][j],One );
add( dp[i%2][j],dp[(i-1)%2][j-1] );
}
}
}
printf("%d",dp[Len%2][len].num[dp[Len%2][len].len-1]);
for( int i = dp[Len%2][len].len-2; i >= 0; i -- ){
printf("%08d",dp[Len%2][len].num[i]);
}
puts("");
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("data.txt","r",stdin);
#endif
int cas;
One.len = 1; One.num[0] = 1;
scanf("%d ",&cas);
while( cas -- )
{
scanf("%s %s",Str,str);
GetDp();
}
return 0;
}