两个字符串一个str,一个word,v[i]表示word中的第i个字符在str中出现的位置
状态转移方程是
if j>=v[i] 1.若word[i]==str[j] 则>
else>
需要用到大数,还用到了滚动数组。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define ll long long #define MAXN 105 using namespace std; void BigAdd(char *a,char *b,char *back) { char c[MAXN]= {0}; int p=0,up=0; for(int i=strlen(a)-1,j=strlen(b)-1; i>=0||j>=0; --i,--j) { int x,y,z; if(i<0) x=0; else x=a[i]-'0'; if(j<0) y=0; else y=b[j]-'0'; z=x+y+up; up=z/10; c[p++]=z%10+'0'; } if(up) c[p++]='1'; c[p]=0; int q=0; for(int i=p-1; i>=0; --i) back[q++]=c[i]; if(!q) back[q++]='0'; back[q]=0; } int Compare(char* a,char* b) //a>b 返回1,a<b返回-1,相同返回0 { int la=strlen(a),lb=strlen(b); if(la>lb) return 1; else if(la<lb) return -1; else return strcmp(a,b); } char dp[2][10005][105]; int v[105],l,L; void Swap() { for(int i=1; i<=L; ++i) swap(dp[0][i],dp[1][i]); } int main() { int T; scanf("%d",&T); while(T--) { char str[10005],word[105]; scanf("%s%s",str+1,word+1); l=strlen(word+1),L=strlen(str+1); strcpy(dp[1][0],"0"); for(int i=0; i<=10003; ++i) strcpy(dp[0][i],"1"); memset(v,0,sizeof(v)); int q=1; for(int i=1; str[i]; ++i) { if(str[i]==word[q]) v[q++]=i; } if(q<l) { puts("0"); continue; } for(int i=1; word[i]; ++i) { for(int j=1; str[j]; ++j) { if(j>=v[i]) { if(word[i]==str[j]) BigAdd(dp[0][j-1],dp[1][j-1],dp[1][j]); else strcpy(dp[1][j],dp[1][j-1]); } else strcpy(dp[1][j],"0"); } Swap(); } puts(dp[0][L]); } return 0; }