#include<iostream>
using namespace std;
int n,m,k;
char a[1145],b[228];//ab串 
int dp[2][205][205][2],r;//考虑递推永远只用前一组,直接滚动数组,留一个暂存 
const int mod=1000000007;
int main(){
	cin>>n>>m>>k;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=m;i++) cin>>b[i];
	for(int i=1;i<=n;i++){//遍历a,取出字符 
		dp[r][0][0][0]=1;//什么也不做也是一种,边界很关键,递推会用到 
		r=(r+1)%2;//滚动 
		for(int j=1;j<=m;j++){//遍历b,匹配字符 
			for(int s=1;s<=k;s++){//不同的子串数,递推 
				if(a[i]==b[j]) {
					dp[r][j][s][1]=(dp[(r+1)%2][j-1][s][1]+(dp[(r+1)%2][j-1][s-1][1]+dp[(r+1)%2][j-1][s-1][0])%mod)%mod;//只要相加了就要mod,否则有爆的风险 
				}//(r+1)%2就是前一组,这里要分类讨论,即选上这个字符后是断开自成新串还是连着上一个串,由于都要选所以前面都是[(r+1)%2][j-1] 
				//如果是连着上一个串说明s的个数不变,实际数量完全等同于dp[(r+1)%2][j-1][s][1] 
				//如果是断开自成新串说明到了这里s的数量加了1,那么上一个是s-1
				//由于上一个无论选没选不影响断开,所以加上上一个的选或不选,即为dp[(r+1)%2][j-1][s-1][1]+dp[(r+1)%2][j-1][s-1][0] 
				else{
					dp[r][j][s][1]=0;
				}//字符不匹配没得选,0 
				dp[r][j][s][0]=(dp[(r+1)%2][j][s][0]+dp[(r+1)%2][j][s][1])%mod;
				//这个不选?说明b的字符数(j)没变,把前一组选和不选的都加起来 
			}
		}
	}
	cout<<(dp[r][m][k][0]+dp[r][m][k][1])%mod;//最后一个可以选或不选,都要加 
	return 0;
}

0 comments

No comments so far...