問題の意味:二つの文字列、所定の第一のサブ求め2番目の文字列の順序に従って第二、及び第一部分文字列と文字列マッチングに一致する文字列で。
それ以外の場合はMLEなり、DPを最適化するには、スクロール配列を使用します。
セットF [I] [J] [K] [0/1] F [I] [J] [K] [0/1] F [ I ] [ J ] [ K ] [ 0 / 1は】特定を使用するかどうかを示しますk番目の文字列で使用されるi番目の文字の文字列、および文字列Bに(必ずしも1は定数であり、0を表していない)最初のj個の文字にマッチします
状態遷移方程式:
F [I] [J] [K] [0] = F [I-1]〜[J] [K] [0] + F [I-1]〜[J] [K] [1]〜[I] F [ J] [1] K] [0] = F [I-1]〜[J] [K] [0] + F [I-1]〜[J] [K] fは[ I ] [ J ] [ K ] [ 0 ] = F [ I - 1 ] [ J ] [ K ] [ 0 ] + F [ I - 1 ] [ J ] [ K ] [ 1 ]
([I] == B [J])場合
F [I] [J] [K] [1] = F [I-1] [J-1] [K-1] [1] + F [I-1] [J-1] [K-1] [0] + F [I-1] [J-1] [K] [1]〜[I] [J] [K] [1] Fを= [I-1] [J-1] [K-1 F ] [1] + F [I-1] [J-1] [K-1] [0] + F [I-1] [J-1] [K] [1] F [ I ] [ J ] [ K ] [ 1 ] = F [ I - 1 ] [ J - 1 ] [ K - 1 ] [ 1 ] + F [ I - 1 ] [ J - 1 ] [ K - 1 ][ 0 ] + F [ I - 1 ] [ J - 1 ] [ K ] [ 1 ]
コードを接続します。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int mod = 1000000007;
const int N = 1011;
int n,m,sum;
int f[2][N][N][2];
char a[N],b[N];
int main()
{
scanf("%d%d%d",&n,&m,&sum);
scanf("%s%s",a+1,b+1);
f[0][0][0][0]=1;//初始化
for(int i=1;i<=n;i++){
int op=i&1;
f[op][0][0][0]=1;//初始化
for(int j=1;j<=min(i,m);j++)
for(int k=1;k<=min(j,sum);k++){
f[op][j][k][0]=f[op][j][k][1]=0;//滚动数组覆盖
f[op][j][k][0]=(f[op^1][j][k][0]+f[op^1][j][k][1])%mod;
if(a[i]==b[j]){
f[op][j][k][1]=((f[op^1][j-1][k-1][1]+f[op^1][j-1][k-1][0])%mod+f[op^1][j-1][k][1])%mod;
}
}
}
printf("%d",(f[n&1][m][sum][1]+f[n&1][m][sum][0])%mod);
return 0;
}