NOIP2015子串题解
2017-09-26 20:19
169 查看
题目地址:
http://fzoj.xndxfz.com/JudgeOnline/problem.php?id=1645题目描述
有两个仅包含小写英文字母的字符串A和B。现在要从字符串A中取出k个 互不重叠 的非空子串,
然后把这k个子串按照其在字符串A中出现的顺序 依次连接 起来得到一个新的字符串,
请问有多少种方案可以使得这个新串与字符串B相等?注意:子串取出的位置不同也认为是不同的方案。
输入
第一行是三个正整数n,m,k,分别表示字符串A的长度,字符串B的长度,以及问题描述中所提到的k,每两个整数之间用一个空格隔开。
第二行包含一个长度为n的字符串,表示字符串A。
第三行包含一个长度为m的字符串,表示字符串B。
输出
输出共一行,包含一个整数,表示所求方案数。由于答案可能很大,所以这里要求输出答案对1,000,000,007取模的结果。
样例输入
6 3 1aabaab aab
样例输出
2题解:
DP。这题的代码很短,但是个人感觉很难想状态和状态转移方程。我也是在洛谷上看了题解才写出来的。s[i][j][k]表示A字符串已经选到了第i个,B字符串已经选到了第j个,在这个过程中一共选择了k个字符串,并且A[I]这个字符必须要选。
f[i][j][k]表示A字符串已经选到了第i个,B字符串已经选到了第j个,在这个过程中一共选择了k个字符串,并且A[I]这个字符不一定要选。
然后就可以推出状态转移方程式。
先是s[i][j][k],当A[i]==B[j]时,s[i][j][k]可以由两种情况相加。一个是将A[i]和B[j]单独当作一个新的字符串的情况也就是s[i][j][k]+=f[i-1][j-1][k-1],还有一种就是A[I]是A[I-1]所在的子串的延续,所以s[i][j][k]+=s[i-1][j-1][k]。
所以s[i][j][k] = (f[i-1][j - 1][k - 1] + s[i-1][j - 1][k]) % mod;
然后是f[i][j][k],这种情况下不要求选择A[i],所以f[i][j][k]也可以由两种情况相加。也就是f[i][j][k] = (f[i-1][j][k] + s[i][j][k]) % mod;
下面贴代码吧
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int f[2][2000][2000],n,m,K,s[2][2000][2000],mod= 1000000007; char a[1000], b[1000]; void Init() { memset(f, 0, sizeof(f)); memset(a, 0, sizeof(a)); memset(b, 0, sizeof(b)); memset(s, 0, sizeof(s)); scanf("%d%d%d", &n, &m, &K); int i; char ch; scanf("%s", a+1); scanf("%s", b+1); f[0][0][0] = 1; } void work() { int i, j, k; int now=1, fron=0; for (i = 1; i <= n; i++) { f[now][0][0] = 1; for (j = 1; j <= m; j++) { for (k = 1; k <= K; k++) { if (a[i] == b[j]) { s[now][j][k] = (f[fron][j - 1][k - 1] + s[fron][j - 1][k]) % mod; } else { s[now][j][k] = 0; } f[now][j][k] = (f[fron][j][k] + s[now][j][k]) % mod; // printf("%d %d %d %d %d\n", i, j, k, s[now][j][k], f[now][j][k]); } } swap(now, fron); } printf("%d", f[fron][m][K]); } int main() { // freopen("testdata.in", "r", stdin); Init(); work(); // printf("%s\n", a + 1); // printf("%s\n", b + 1); return 0; }
相关文章推荐
- noip2015 子串 dp
- [NOIP2015]子串
- NOIP2015 子串 解题报告(DP)
- 【noip2015】子串
- 【uoj149】 NOIP2015—子串
- NOIP2015 子串
- codevs 4560 NOIP2015 D2T2 子串
- noip2015 D2T2 子串
- [NOIP2015] 子串substring 题解
- NOIP2015提高组Day2 第二题 子串 解题报告
- 【NOIP2015】洛谷2679 子串
- NOIP2015 day2t2 子串
- 【NOIp 2015】【动态规划】子串
- 【Noip 2015】 子串 解题报告
- UOJ #149 [NOIP 2015] 子串
- NOIP2015复赛提高组day2(A:跳石头 B:子串 C:运输计划)
- 洛谷P2679 子串(NOIP2015)
- Codevs 4560 NOIP2015 D2T2 子串
- 【NOIP2015】 子串
- 解题报告 NOIP2015 子串