首页 > 其他 > 详细

[NOIP2015]子串

时间:2018-10-22 22:38:34      阅读:220      评论:0      收藏:0      [点我收藏+]

嘟嘟嘟

刚开始我以为是kmp+dp,后来发现其实没那么复杂。

令dp[i][j][h][0/1]表示A串到第 i 位,B串到第 j 位,其中A串取了k个子串时,A取/不取的方案数。那么转移方程就很容易的写出来了:

  dp[i][j][h][0] = dp[i - 1][j][h][0] + dp[i - 1][j][h][1]

  dp[i][j][h][1] = dp[i - 1][j - 1][h][1] + dp[i - 1][j - 1][h - 1][1] + dp[i - 1][j - 1][h - 1][0]   (a[i] == b[j])

初始化dp[i][0][0][0] = 1. (0 <= i <= n) (我就因为dp[0][0][0][0]没初始化debug了好半天!)

然后用滚动数组把第一位优化掉,就A了。

技术分享图片
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<cctype>
 8 #include<vector>
 9 #include<stack>
10 #include<queue>
11 using namespace std;
12 #define enter puts("") 
13 #define space putchar(‘ ‘)
14 #define Mem(a, x) memset(a, x, sizeof(a))
15 #define rg register
16 typedef long long ll;
17 typedef double db;
18 const int INF = 0x3f3f3f3f;
19 const db eps = 1e-8;
20 const ll mod = 1e9 + 7;
21 const int maxn = 1e3 + 5;
22 const int maxm = 205;
23 inline ll read()
24 {
25   ll ans = 0;
26   char ch = getchar(), last =  ;
27   while(!isdigit(ch)) {last = ch; ch = getchar();}
28   while(isdigit(ch)) {ans = ans * 10 + ch - 0; ch = getchar();}
29   if(last == -) ans = -ans;
30   return ans;
31 }
32 inline void write(ll x)
33 {
34   if(x < 0) x = -x, putchar(-);
35   if(x >= 10) write(x / 10);
36   putchar(x % 10 + 0);
37 }
38 
39 int n, m, k;
40 char a[maxn], b[maxm];
41 ll dp[2][maxm][maxm][2];
42 
43 int main()
44 {
45     n = read(); m = read(); k = read();
46     scanf("%s%s", a + 1, b + 1);
47      int o = 0;
48     for(int i = 1; i <= n; ++i, o ^= 1)
49     {
50         dp[o ^ 1][0][0][0] = 1;
51         for(int j = 1; j <= min(i, m); ++j)
52               for(int h = 1; h <= min(j, k); ++h)
53             {
54                 dp[o][j][h][0] = dp[o][j][h][1] = 0;
55                   dp[o][j][h][0] = (dp[o ^ 1][j][h][0] + dp[o ^ 1][j][h][1]) % mod;
56                   if(a[i] == b[j])
57                   {
58                     dp[o][j][h][1] = (dp[o ^ 1][j - 1][h][1] + dp[o ^ 1][j - 1][h - 1][1]) % mod;
59                       dp[o][j][h][1] = (dp[o][j][h][1] + dp[o ^ 1][j - 1][h - 1][0]) % mod;
60                   }
61             }
62     }
63       write((dp[o ^ 1][m][k][0] + dp[o ^ 1][m][k][1]) % mod), enter;
64       return 0;
65 }
View Code

 

[NOIP2015]子串

原文:https://www.cnblogs.com/mrclr/p/9833585.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!