只要处理长度等于t的.
转移方程没想出来QAQ
$dp(i,j,0)$代表到$s[i]$为止有多少个前缀序列与$t[0\cdots j]$相同
所以有$dp(i,j,0)=dp(i-1,j,0)+s[i]==t[j]?dp(i-1,j-1,0):0;$
$dp(i,j,1)$代表到$s[i]$为止有多少个子序列大于$t[0\cdots j]$
故有$dp(i,j,1)=dp(i-1,j,1)+(s[i]>t[j])*dp(i,j-1,0)+(j>0)*dp(i-1,j-1,0)$
#include<bits/stdc++.h> using namespace std; char s[3050],t[3050]; typedef long long ll; ll dp[3005][3005][2]; ll C[3003][3003]; ll mod=998244353; void init() { for(int i=0;i<3001;i++){ C[i][i]=1; C[i][0]=1; } for(int i=1;i<3001;i++){ for(int j=i+1;j<3001;j++){ C[j][i]=(C[j-1][i-1]+C[j-1][i])%mod; } } } int main() { int T; int n,m; ll ans; init(); scanf("%d",&T); while(T--){ ans=0; scanf("%d%d",&m,&n); scanf("%s",s); scanf("%s",t); for(int i=0;i<=max(m,n);i++) dp[i][0][1]=dp[i][0][0]=1; // for(int i=0;i<=n;i++)dp[0][i]=1; for(int i=0;i<m;i++){ for(int j=0;j<n;j++){ dp[i+1][j+1][0]=((dp[i][j][0])*(s[i]==t[j])+dp[i][j+1][0])%mod; dp[i+1][j+1][1]=(dp[i][j+1][1]+(s[i]>t[j])*dp[i][j][0]+(j>0)*dp[i][j][1])%mod; // cout<<dp[i+1][j+1][1]<<' '; } // cout<<'\n'; // cout<<i<<" "<<ans<<'\n'; } ans=dp[m][n][1]; //cout<<ans<<'\n'; for(int k=n+1;k<=m;k++) for(int i=1;i+k-1<=m;i++){ if(s[i-1]!='0') ans=(ans+C[m-i][k-1])%mod; } cout<<ans<<'\n'; } }