Description:
给定 (A,B) 两个字符串,把 (A) 串分成 (k) 个连续不交叉子串,求把所有字串按顺序排起来得到 (B) 串的方案数。
Solution:
设 (f_{i,j,k,1/0}) 表示 (A_{1..i} , B_{1..j}) 且子串数为 (k) 的方案数。
则:
好像也可以设 (f_{i,j,k,0}) 表示选不选都行的方案数,同理方程就好推了qwq
然后滚动优化一下就好了。
(话说四维层面上的东西真是不好想
Code:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4;
const int M = 1e3;
const int mod = 1e9+7;
int n,m,K;
int f[M][M][2];
char a[N],b[N];
int main()
{
scanf("%d%d%d
",&n,&m,&K);
gets(a+1);gets(b+1);
f[0][0][0]=1;
for(int i=1;i<=n;++i)
{
for(int j=min(i,m);j>=1;--j)
{
for(int k=1;k<=min(j,K);++k)
{
if(a[i]==b[j])
{
f[j][k][0]=(f[j][k][0]+f[j][k][1])%mod;
f[j][k][1]=((f[j-1][k-1][0]+f[j-1][k-1][1])%mod+f[j-1][k][1])%mod;//这里 % 一次导致调了1h-,真·细节决定成败。。。
}
else if(a[i]!=b[j])
{
f[j][k][0]=(f[j][k][0]+f[j][k][1])%mod;
f[j][k][1]=0;
}
}
}
}
printf("%d
",(f[m][K][0]+f[m][K][1])%mod);
return 0;
}
Question:
dp的初值问题:比如这道题,为啥 (f_{0,0,1} ot =1) ?