NOIP2015 子串 DP

f[i][j][k][0]表示a串匹配到第i个字符 b串匹配到第j个字符 当前已经取了k串 a[i]不和b[j]匹配

f[i][j][k][1]```````````````````````````````````````````````````````````````````````````````````a[i]和b[j]匹配

分以下情况:
1、A[i]!=B[j]:f[i-1][j][k][0]+f[i-1][j][k][1]
2、A[i]=B[j]时,分三种情况:
      ①不用A[i]匹配B[j]:f[i-1][j][k][0]+f[i-1][j][k][1]
      ②A[i]与B[j]匹配且A[i]作为独立的新的一个子串:f[i-1][j-1][k-1][1]+f[i-1][j-1][k-1][0]
      ③A[i]与B[j]匹配且A[i]不是作为独立的新的一个子串:f[i-1][j-1][k-1][1] 因为只有 a[i-1]和b[j-1]匹配,a[i]和b[j]才能接着匹配。


另外,你需要一个滚动数组。。。


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
char a[1005],b[205];
int i,j,o,last,now,mod,f[2][205][205][2],n,m,k;
int main()
{ scanf("%d%d%d\n",&n,&m,&k);
  scanf("%s\n",a+1);
  scanf("%s\n",b+1);
  mod=1000000007;
  last=1;
  for (i=1;i<=n;i++)
  { memset(f[last],0,sizeof(f[last]));
	now=last;last=1-now;
	f[last][0][0][0]=1;
	for (j=1;j<=m;j++)
	{ for (o=1;o<=k;o++)
	  { f[now][j][o][0]=(f[last][j][o][0]+f[last][j][o][1])%mod;
	    if (a[i]==b[j])
	    f[now][j][o][1]=(((f[last][j-1][o-1][0]+f[last][j-1][o-1][1])%mod)+
		                  f[last][j-1][o][1])%mod;  
	  }
    }
  }
  printf("%d",(f[now][m][k][0]+f[now][m][k][1])%mod);
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值