[NOIP2015]子串

嘟嘟嘟

刚开始我以为是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

 

posted @ 2018-10-22 22:31  mrclr  阅读(137)  评论(0编辑  收藏  举报