【NOIP2015】【洛谷2679】子串
2017-05-11 00:45
197 查看
链接:https://www.luogu.org/problem/show?pid=2679
题解:
1.求方案数,结合数据范围,可以考虑用DP解
2.令f[i][j][k][0/1]表示A串用了前i个字符,B串已覆盖前j个字符,目前为止已经选了k个子串,最后的0/1表示A串的这个字符选了没有(0没选,1选了)。
3.若当前字符选了,显然当且仅当a[i]=b[j]的时候它才有意义,否则f[i][j][k][1]=0。
到这个状态有三种方法:
(1). 上一位不选,新开一个子串
(2). 上一位选了,延续这个子串
(3). 上一位选了,新开一个子串
根据dp数组的定义,可以得到
f[i][j][k][1]=f[i-1][j-1][k-1][0]+f[i-1][j-1][k][1]+f[i-1][j-1][k-1][1]。
4.若当前字符不选。
(1). 上一位不选,现在仍然不选
(2). 上一位选了,现在不选
故f[i][j][k][0]=f[i-1][j][k][0]+f[i-1][j][k][1]。
总的方程式
f[i][j][k][1]=f[i-1][j-1][k-1][0]+f[i-1][j-1][k][1]+f[i-1][j-1][k-1]1
f[i][j][k][1]=0(a[i]!=b[j])
f[i][j][k][0]=f[i-1][j][k][0]+f[i-1][j][k][1]
边界:f[0][0][0][0]=1。
最终答案:f
[m][k][0]+f
[m][k][1]。
复杂度O(nmk)
考虑到空间可能爆掉,用滚动数组压掉第一维即可
写的很心累QAQ
各种细节错QAQ
代码
题解:
1.求方案数,结合数据范围,可以考虑用DP解
2.令f[i][j][k][0/1]表示A串用了前i个字符,B串已覆盖前j个字符,目前为止已经选了k个子串,最后的0/1表示A串的这个字符选了没有(0没选,1选了)。
3.若当前字符选了,显然当且仅当a[i]=b[j]的时候它才有意义,否则f[i][j][k][1]=0。
到这个状态有三种方法:
(1). 上一位不选,新开一个子串
(2). 上一位选了,延续这个子串
(3). 上一位选了,新开一个子串
根据dp数组的定义,可以得到
f[i][j][k][1]=f[i-1][j-1][k-1][0]+f[i-1][j-1][k][1]+f[i-1][j-1][k-1][1]。
4.若当前字符不选。
(1). 上一位不选,现在仍然不选
(2). 上一位选了,现在不选
故f[i][j][k][0]=f[i-1][j][k][0]+f[i-1][j][k][1]。
总的方程式
f[i][j][k][1]=f[i-1][j-1][k-1][0]+f[i-1][j-1][k][1]+f[i-1][j-1][k-1]1
f[i][j][k][1]=0(a[i]!=b[j])
f[i][j][k][0]=f[i-1][j][k][0]+f[i-1][j][k][1]
边界:f[0][0][0][0]=1。
最终答案:f
[m][k][0]+f
[m][k][1]。
复杂度O(nmk)
考虑到空间可能爆掉,用滚动数组压掉第一维即可
写的很心累QAQ
各种细节错QAQ
代码
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; #define MOD 1000000007 #define Maxn 2020 int f[2][Maxn][Maxn][2]; int main() { // freopen("2015substring.in","r",stdin); // freopen("2015substring.out","w",stdout); int n,m,k,d=1; char a[Maxn],b[Maxn]; scanf("%d %d %d %s %s",&n,&m,&k,a+1,b+1); f[0][0][0][0]=1; for(int i=1;i<=n;i++,d=!d) for(int j=0;j<=i&&j<=m;j++) for(int h=0;h<=k&&h<=j&&h<=i;h++) { f[d][j][h][0]=0; if(i-1>=j) { (f[d][j][h][0]+=f[!d][j][h][0])%=MOD; (f[d][j][h][0]+=f[!d][j][h][1])%=MOD; } f[d][j][h][1]=0; if(j&&a[i]==b[j]) { if(h) { (f[d][j][h][1]+=f[!d][j-1][h-1][0])%=MOD; (f[d][j][h][1]+=f[!d][j-1][h-1][1])%=MOD; } (f[d][j][h][1]+=f[!d][j-1][h][1])%=MOD; } } printf("%d\n",f[!d][m][k][0]+f[!d][m][k][1]); return 0; }
相关文章推荐
- 【NOIP2015-Day2-T2】洛谷2679:子串 题解
- 洛谷 oj 2679 【NOIP2015】子串(一堆智障错误)Mod 、O(c) etc.
- 【NOIP2015】洛谷2679 子串
- [luogu-2679]noip2015day2-T2 子串 题解
- LuoguP2679[NOIP2015] 子串 解题报告【多维DP】
- 洛谷 P2679 [NOIP2015 D2T2] 子串
- noip2015 子串 luogu2679
- [NOIP2015] 提高组 洛谷P2679 子串
- 洛谷P2679 NOIP2015 子串
- 洛谷 2676 [NOIP2015] 子串 DP
- [NOIP2015] 提高组 洛谷P2615 神奇的幻方
- NOIP 2015 子串 (DP)
- NOIP 2015 子串
- [抄][1]NOIP 2015 子串
- UOJ149 【NOIP2015】子串
- |洛谷|NOIP2015|堆|P2672 推销员
- NOIP2015 D2T2子串
- 【noip2015】子串
- NOIP2015复赛提高组day2(A:跳石头 B:子串 C:运输计划)
- 洛谷 2680[NOIP2015] 运输计划 二分+lca+树上差分+dfs序