zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    VMware 虚拟机扩容磁盘
    记录一次Jenkins多分支构建问题
    ceph 集群快速部署
    阿里云EMAS发布套餐订阅云服务
    我研究过的OA产品这是简单的总结
    Hello,OA!Hello,工作流!寻找OA和工作流的旅途记录
    疑难杂症1-去掉网站里的特殊编码&#65279
    IIS 平台NET无后缀名伪静态实现办法
    让人无语的面试题!!排序!你试试?
    优秀的大企业报告辅助撰写系统介绍
  • 原文地址:https://www.cnblogs.com/rausen/p/4264103.html
Copyright © 2011-2022 走看看