题面
Description
Input
Output
Sample Input
输入1:
6 3 1
aabaab
aab
输入2:
6 3 2
aabaab
aab
输入3:
6 3 3
aabaab
aab
Sample Output
输出1:
2
输出2:
7
输出3:
7
Data Constraint
思路
这道题我们可以考虑用 D P DP DP来做。
设 f i , j , k , 0 f_{i,j,k,0} fi,j,k,0表示a序列枚举到i位置,b序列枚举到j位置,选了k个子串,当前不选,则 f i , j , k , 1 f_{i,j,k,1} fi,j,k,1表示选。
接着我们可以分两种情况讨论:
-
a i ! = b j a_i!=b_j ai!=bj
当前转移方程即为:
f i , j , k , 1 = 0 f_{i,j,k,1}=0 fi,j,k,1=0
f i , j , k , 0 = f i − 1 , j , k , 0 + f i − 1 , j , k , 1 f_{i,j,k,0}=f_{i-1,j,k,0}+f_{i-1,j,k,1} fi,j,k,0=fi−1,j,k,0+fi−1,j,k,1 -
a i = b j a_i=b_j ai=bj
当前转移方程即为:
f i , j , k , 0 = f i − 1 , j , k , 0 + f i − 1 , j , k , 1 f_{i,j,k,0}=f_{i-1,j,k,0}+f_{i-1,j,k,1} fi,j,k,0=fi−1,j,k,0+fi−1,j,k,1
当前选的情况又可以分为三种情况讨论:
1 ) 1) 1) .前面有子串,不用新增
f i − 1 , j − 1 , k , 1 ~~~~~~f_{i-1,j-1,k,1} fi−1,j−1,k,1
2 ) 2) 2) .前面有子串,但新增一子串
f i − 1 , j − 1 , k − 1 , 1 ~~~~~~f_{i-1,j-1,k-1,1} fi−1,j−1,k−1,1
3 ) 3) 3) .前面一个无子串,新增一子串
f i − 1 , j − 1 , k − 1 , 0 ~~~~~~f_{i-1,j-1,k-1,0} fi−1,j−1,k−1,0
将上述方案加起来即为 f i , j , k , 1 f_{i,j,k,1} fi,j,k,1的转移式了。
答案: f n , m , k , 0 + f n , m , k , 1 f_{n,m,k,0}+f_{n,m,k,1} fn,m,k,0+fn,m,k,1
初始化: f 0 , 0 , 0 , 0 = f 1 , 0 , 0 , 0 = 1 f_{0,0,0,0}=f_{1,0,0,0}=1 f0,0,0,0=f1,0,0,0=1
然而我们会发现如果这样做的话,我们就会
于是我们可以考虑开一个滚动数组,因为第 i i i位只用考虑第 i − 1 i-1 i−1位的数,所以我们只需要将 i i i位置开2位。
Code
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define mod 1000000007
using namespace std;
int n,m,s,len,len1,ans;
char a[1005],b[205];
long long f[2][205][205][2];
int main()
{
freopen("substring.in","r",stdin);
freopen("substring.out","w",stdout);
scanf("%d%d%d",&n,&m,&s);
scanf("%s",a+1);
scanf("%s",b+1);
f[0][0][0][0]=f[1][0][0][0]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int k=1;k<=s;k++)
{
if(a[i]!=b[j])
{
f[i%2][j][k][1]=0;
f[i%2][j][k][0]=(f[(i-1)%2][j][k][0]+f[(i-1)%2][j][k][1])%mod;
}
else
{
f[i%2][j][k][0]=(f[(i-1)%2][j][k][0]+f[(i-1)%2][j][k][1])%mod;
f[i%2][j][k][1]=(f[(i-1)%2][j-1][k][1]+f[(i-1)%2][j-1][k-1][0]+f[(i-1)%2][j-1][k-1][1])%mod;
}
}
printf("%lld",(f[n%2][m][s][0]+f[n%2][m][s][1])%mod);
}