有两个仅包含小写英文字母的字符串A和B。现在要从字符串A中取出k个互不重叠的非空子串,然后把这k个子串按照其在字符串A中出现的顺序依次连接起来得到一个新的字符串,请问有多少种方案可以使得这个新串与字符串 B 相等?注意:子串取出的位置不同也认为是不同的方案。
-----------------------------------------------------------------------------分割线-------------------------------------------------------------------------------------------------
f[i,j,k] (当前匹配到第k组,匹配完成第j位且最后一位是a[i]) s[i,j,k]=∑f[x,j,k](0<x<=i)前缀和
f[i,j,k]=0(a[i]<>b[j])当前位不相同
f[i,j,k]=s[i-1,j-1,k-1](a[i]=b[j]) and (a[i-1]<>b[j-1])前一位不相同
f[i,j,k]=s[i-1,j-1,k-1]+f[i-1,k-1,k](a[i]=b[i]) and (a[i-1]=b[j-1])
此题需要(空间)循环数组(时间)前缀和的优化方可AK
const
model=1000000007;
var
ans:qword;
a,b:array[1..1000] of char;
f,s:array[0..1000,0..1,1..200] of qword;
i,j,k,ki,ji,n,m:longint;
procedure p1;
begin
assign(input,'substring.in');
assign(output,'substring.out');
reset(input);
rewrite(output);
end;
procedure p2;
begin
close(input);
close(output);
end;
begin
p1;
readln(n,m,k);
for i:=1 to n do read(a[i]);readln;
for i:=1 to m do read(b[i]);readln;
for i:=1 to n do begin
if a[i]=b[1] then f[i,1,1]:=1 else f[i,1,1]:=0;
s[i,1,1]:=s[i-1,1,1]+f[i,1,1];
end;
for j:=2 to m do
for ki:=1 to k do begin
ji:=j and 1;
for i:=0 to n do begin s[i,ji,ki]:=0;f[i,ji,ki]:=0;end;
for i:=j to n-m+j do begin
if a[i]<>b[j] then f[i,ji,ki]:=0
else begin
if ki>1 then f[i,ji,ki]:=s[i-1,ji xor 1,ki-1];
if a[i-1]=b[j-1] then f[i,ji,ki]:=(f[i,ji,ki]+f[i-1,ji xor 1,ki]) mod model;
end;
s[i,ji,ki]:=(s[i-1,ji,ki]+f[i,ji,ki]) mod model;
end;
end;
writeln(s[n,m and 1,k]);
p2;
end.