• BZOJ2958 序列染色


    果然清华集训的题目。。。显然的DP题但是不会做。。。

    我们令f[i][j][w]表示状态方程

    w表示到了字符串的第w个

    i = 0, 1, 2分别表示k个B和k个W都没填上、k个B填上了k个W没填上、k个B和k个W都填上了三种状态

    j = 0, 1分别表示第w位上填B/W

    于是方程就比较容易列出来了,注意要用到容斥原理

     1 /**************************************************************
     2     Problem: 2958
     3     User: rausen
     4     Language: C++
     5     Result: Accepted
     6     Time:652 ms
     7     Memory:33032 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11  
    12 using namespace std;
    13 const int N = 1000005;
    14 const int mod = 1e9 + 7;
    15  
    16 int n, k;
    17 char st[N];
    18 int s0[N], s1[N], f[3][2][N];
    19  
    20 void read_in() {
    21   int i;
    22   char ch = getchar();
    23   while (ch != 'W' && ch != 'B' && ch != 'X')
    24     ch = getchar();
    25   for (i = 1; i <= n; ++i)
    26     st[i] = ch, ch = getchar();
    27 }
    28  
    29 inline int calc(char c, int *s, int i, int t) {
    30   if (i < k || st[i - k] == c || s[i] - s[i - k]) return 0;
    31   return f[t - 1][i == k ? 0 : 2 - t][i - k];
    32 }
    33  
    34 int main() {
    35   int i;
    36   scanf("%d%d", &n, &k);
    37   read_in();
    38   f[0][0][0] = 1;
    39   for (i = 1; i <= n; ++i) {
    40     s0[i] = s0[i - 1] + (st[i] == 'W');
    41     s1[i] = s1[i - 1] + (st[i] == 'B');
    42     if (st[i] != 'W') {
    43       f[0][0][i] = (0ll + f[0][1][i - 1] + f[0][0][i - 1] - calc('B', s0, i, 1) + mod) % mod;
    44       f[1][0][i] = (0ll + f[1][0][i - 1] + f[1][1][i - 1] + calc('B', s0, i, 1)) % mod;
    45       f[2][0][i] = (0ll + f[2][0][i - 1] + f[2][1][i - 1]) % mod;
    46     }
    47     if (st[i] != 'B') {
    48       f[0][1][i] = (0ll + f[0][1][i - 1] + f[0][0][i - 1]) % mod;
    49       f[1][1][i] = (0ll + f[1][0][i - 1] + f[1][1][i - 1] - calc('W', s1, i, 2) + mod) % mod;
    50       f[2][1][i] = (0ll + f[2][0][i - 1] + f[2][1][i - 1] + calc('W', s1, i, 2)) % mod;
    51     }
    52   }
    53   printf("%d
    ", (f[2][0][n] + f[2][1][n]) % mod);
    54   return 0;
    55 }
    View Code

    (p.s. Orz 江哥...)

    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    线程原理 创建方式
    Chapter17 【异常、线程】
    驱动
    java中Super到底是什么意思
    Java 8后的首个长期支持版本Java 11
    OpenJDK和JDK区别
    异常
    模拟斗地主洗牌发牌
    Debug追踪
    Python 垃圾回收机制详细
  • 原文地址:https://www.cnblogs.com/rausen/p/4264103.html
Copyright © 2020-2023  润新知