NOIP 2015 子串
2017-10-20 08:54
405 查看
评测传送
一开始做就想暴力,蒟蒻的dp实在是太弱了。
言归正传。
我们用f[i][j][p][0/1]表示用了a串前 i 个字符作为p段,匹配了b串前 j 个字符(0表示第i个字符没有用,1表示第i个字符用了)。
那么有f[i][j][p][0]=f[i−1][j][p][1]+f[i−1][j][p][1];
f[i][j][p][1]=f[i−1][j−1][p−1][1]+f[i−1][j−1][p−1][0]+f[i−1][j−1][p][1],(a[i]==b[j])
解释一下第二个式子:
f[i-1][j-1][p][1]+f[i-1][j-1][p-1][1]表示i和前面的第i-1不拼成一串单独作为1串。
f[i-1][j-1][p][1]表示和第i-1合成一串。
数组开不下,因为每次只用到f[i-1],所以用滚动数组就可以了。
一开始做就想暴力,蒟蒻的dp实在是太弱了。
言归正传。
我们用f[i][j][p][0/1]表示用了a串前 i 个字符作为p段,匹配了b串前 j 个字符(0表示第i个字符没有用,1表示第i个字符用了)。
那么有f[i][j][p][0]=f[i−1][j][p][1]+f[i−1][j][p][1];
f[i][j][p][1]=f[i−1][j−1][p−1][1]+f[i−1][j−1][p−1][0]+f[i−1][j−1][p][1],(a[i]==b[j])
解释一下第二个式子:
f[i-1][j-1][p][1]+f[i-1][j-1][p-1][1]表示i和前面的第i-1不拼成一串单独作为1串。
f[i-1][j-1][p][1]表示和第i-1合成一串。
数组开不下,因为每次只用到f[i-1],所以用滚动数组就可以了。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<ctime> #include<queue> #define LL long long using namespace std; const int MOD=1000000007; LL f[3][209][209][3]; int n,m,k; char a[1009],b[309]; LL ans; int main() { freopen("substring.in","r",stdin); scanf("%d%d%d\n",&n,&m,&k); gets(a+1);gets(b+1); f[0][0][0][0]=1; int now=1; for(int i=1;i<=n;i++) { f[now][0][0][0]=1; for(int j=1;j<=m;j++) { for(int p=1;p<=k;p++) { f[now][j][p][0]=f[now][j][p][1]=0;//先将上上次的清空 f[now][j][p][0]=(f[now^1][j][p][0]+f[now^1][j][p][1])%MOD; if(a[i]==b[j]) f[now][j][p][1]=(f[now^1][j-1][p-1][1]+f[now^1][j-1][p-1][0]+f[now^1][j-1][p][1])%MOD; } } now=now^1; } ans=(f[now^1][m][k][1]+f[now^1][m][k][0])%MOD; printf("%lld",ans); }
相关文章推荐
- 【DP】UOJ#149 【NOIP2015】子串
- NOIP2015 子串 【动态规划】
- 【NOIP2015提高组T5】子串-字符串上的动态规划
- 4000 NOIP 2015 提高组 Day2 子串
- 【uoj#149】【NOIP2015】子串 DP
- 【NOIP2015】【洛谷2679】子串
- NOIP2015 Day2 T2 子串
- 洛谷 P2679 [NOIP2015 D2T2] 子串
- NOIP2015 子串
- NOIP2015 子串
- 洛谷P2679 NOIP2015 子串
- [NOIP2015]Day2T2 子串
- noip2015 子串
- [NOIP2015]子串
- 【NOIP】提高组2015 子串
- 【NOIP2015-Day2-T2】洛谷2679:子串 题解
- C++——NOIP2015提高组day2 t2——子串
- NOIP2015 子串 DP
- [UOJ#149][NOIP2015]子串(dp)
- Noip2015 子串 【动态规划】