• [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
  • 相关阅读:
    增长思维——模式&&组织
    BackUP
    增长思维——机会
    Android
    增长思维——作战地图
    Server架构 小知识
    Server
    产品思维——创新模式
    产品思维——用户体验
    博客迁移到~http://zhulingyu.com
  • 原文地址:https://www.cnblogs.com/mrclr/p/9833585.html
Copyright © 2020-2023  润新知