神仙dp
(怎么看每道dp都很神仙啊)
f[i][j]表示第二列匹配到i,用了j个段的方案数 (最后取不取!)
一个个枚举即可!
#include<bits/stdc++.h> using namespace std; #define mod 1000000007 const int N=1005,M=205; int n,m,r; char A[N],B[M]; int f[M][M][2];//f[i][j]表示第二列匹配到i,用了j个段的方案数 (最后取不取!) int g[M][M][2]; inline void print(int x){ for(int i=1;i<M;i++){ for(int j=1;j<M;j++){ for(int k=0;k<2;k++){ if(f[i][j][k]!=0) printf("time:%d,i:%d,j:%d,k:%d,f[i][j][k]:%d\n",x,i,j,k,f[i][j][k]); } } } printf("****************\n"); } inline void memcpy__(){ for(int i=1;i<M;i++) for(int j=1;j<M;j++) for(int k=0;k<2;k++) f[i][j][k]=g[i][j][k]; } int main(){ memset(f,0,sizeof(f)); memset(g,0,sizeof(g)); scanf("%d%d%d",&n,&m,&r); scanf("%s",(A+1)); scanf("%s",(B+1)); g[0][0][0]=1; if(A[1]==B[1]) g[1][1][1]=1; memcpy__(); B[m+1]=‘*‘; for(int i=2;i<=n;i++){ //print(i-1); memset(g,0,sizeof(g)); if(A[i]==B[1]) g[1][1][1]++,g[1][1][1]%=mod; for(int j=1;j<=m;j++){ for(int k=1;k<=r;k++){ g[j][k][0]+=(f[j][k][0]+f[j][k][1])%mod; if(A[i]==B[j]&&j>1) g[j][k][1]+=((f[j-1][k][1]+f[j-1][k-1][0])%mod+f[j-1][k-1][1])%mod; //g[j][k][1]+=f[j][k][1]%mod; g[j][k][0]%=mod; g[j][k][1]%=mod; } } memcpy__(); }//print(n); printf("%d\n",(f[m][r][0]+f[m][r][1])%mod); return 0; }
原文:https://www.cnblogs.com/QYJ060604/p/11508792.html