NOIP2015Day2T2-子串

2.子串

(substring.cpp/c/pas)

【问题描述】

有两个仅包含小写英文字母的字符串A 和B 。现在要从字符串A 中取出k 个互不重叠的非空子串,然后把这k 个子串按照其在字符串A 中出现的顺序依次连接起来得到一个新的字符串,请问有多少种方案可以使得这个新串与字符串B 相等?注意:子串取出的位置不同也认为是不同的方案。

【输入格式】

输入文件名为substring.in 。

第一行是三个正整数n ,m ,k ,分别表示字符串A 的长度,字符串B 的长度,以及问题描述中所提到的k ,每两个整数之间用一个空格隔开。

第二行包含一个长度为n 的字符串,表示字符串A 。

第三行包含一个长度为m 的字符串,表示字符串B 。

【输出格式】

输出文件名为substring.out 。

输出共一行,包含一个整数,表示所求方案数。由于答案可能很大,所以这里要求输出答案对1,000,000,007取模的结果。

NOIP2015提高组复赛 DAY1+DAY2 试题

NOIP2015提高组复赛 DAY1+DAY2 试题

NOIP2015提高组复赛 DAY1+DAY2 试题

【输入输出样例3】

见选手目录下substring/substring1.in与substring/substring1.ans。 见选手目录下substring/substring3.in与substring/substring3.ans。


一看到这题,就想到了DP。很明显可以看到三维的dp状态,dp[i,j,k],表示A串到i位置,B串到j位置,已经用了k个串的方案数。

var 
  mo,n,m,k,i,j,p,now,pre,s:longint;ans:int64;a,b:ansistring; 
  f:array[0..1,0..1000,0..1000]of longint; 
begin
  mo:=1000000007; 
  readln(n,m,k); 
  readln(a); 
  readln(b); 
  for i:=1 to n do if a[i]=b[1] then f[0,i,1]:=1; 
  for p:=2 to m do
  begin
    pre:=1-now; 
    for j:=1 to k do
    begin
      s:=0; 
      for i:=1 to n do
      begin
        s:=(s+f[now,i-1,j-1])mod mo; 
        if a[i]=b[p] then f[pre,i,j]:=(f[now,i-1,j]+s)mod mo 
          else f[pre,i,j]:=0; 
      end; 
    end; 
    now:=pre; 
  end; 
  for i:=1 to n do ans:=(ans+f[now,i,k])mod mo; 
  writeln(ans); 
end. 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JackflyDC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值