bzoj2958 序列染色

题目传送门

Description

  给出一个长度为N由B、W、X三种字符组成的字符串S,你需要把每一个X染成B或W中的一个。

  对于给出的K,问有多少种染色方式使得存在整数a,b,c,d使得:

  1<=a<=b<c<=d<=N

  Sa,Sa+1,...,Sb均为B

  Sc,Sc+1,...,Sd均为W

  其中b=a+K-1,d=c+K-1

  由于方法可能很多,因此只需要输出最后的答案对109+7取模的结果。

Input

  第一行两个正整数N,K

  第二行一个长度为N的字符串S

Output

  一行一个整数表示答案%(109+7)。

Sample Input

5 2

XXXXX

Sample Output

4

数据约定

  对于20%的数据,N<=20

  对于50%的数据,N<=2000

  对于100%的数据,1<=N<=106,1<=K<=106

Solution

  很容易想到N^2的做法(简单的DP)。

  f[i][j][h][s]——i表示到了第i个字符,状态为j(0表示没有k个B,1表示有k个B没有k个W,2表示既有k个B又有k个W),最后一位为h(0表示B,1表示W),最后一位有连续s个。

  具体转移就不说了。

  其实s是不用记的(F[i][j][h]),那怎么转移状态j呢?

  现有状态需要保证连续的B后有一个W,连续的W后有一个B,答案就是F[n+1][2][0],在第n+1为设为B,最后一位选B不会对答案有影响。

  假如第i位是B,F[i][j][0]=F[i-1][j][1]+F[i-1][j][0];(其他同理,先不考虑j)

  若第i-k+1位到第i位没有W(可以把所有的X变为B,使得有k个B),F[i][1][0]=F[i][1][0]+F[i-k][0][1];

  但依照第一条原则,F[i][0][0]是胡乱转移的,而从F[i-k][0][1]转移会有已经满足中间有k个B的情况,减掉重复的即可。F[i][0][0]=F[i][0][0]-F[i-k][0][1];

PS:DP神题,容斥大法好 残忍暴力水50。

CODE

#include<cstdio>
#include<algorithm> #define imax(a,b) ((a>b)?(a):(b)) typedef long long ll; using namespace std; typedef long long ll; const ll mods=1e9+7;
const int N=1000010;
int n,m,B[N],W[N];
ll F[N][3][2];
char st[N]; int main()
{
freopen("2237.in","r",stdin);
freopen("2237.out","w",stdout);
scanf("%d%d%s",&n,&m,st+1);
st[++n]='X';
for(int i=1;i<=n;i++)
{
B[i]=B[i-1]+(st[i]=='B');
W[i]=W[i-1]+(st[i]=='W');
}
F[0][0][1]=1ll;
for(int i=1;i<=n;i++)
{
if(st[i]!='W')
for(int j=0;j<3;j++) F[i][j][0]=(F[i-1][j][1]+F[i-1][j][0])%mods;
if(st[i]!='B')
for(int j=0;j<3;j++) F[i][j][1]=(F[i-1][j][1]+F[i-1][j][0])%mods;
if(i<m) continue;
if(st[i]!='W' && W[i]==W[i-m])
{
F[i][1][0]=(F[i][1][0]+F[i-m][0][1])%mods;
F[i][0][0]=(F[i][0][0]-F[i-m][0][1])%mods;
}
if(st[i]!='B' && B[i]==B[i-m])
{
F[i][2][1]=(F[i][2][1]+F[i-m][1][0])%mods;
F[i][1][1]=(F[i][1][1]-F[i-m][1][0])%mods;
}
}
printf("%lld\n",(F[n][2][0]+mods)%mods);
return 0;
}

BZOJ:2958 序列染色 DP的更多相关文章

  1. bzoj2958: 序列染色(DP)

    2958: 序列染色 题目:传送门 题解: 大难题啊(还是我太菜了) %一发大佬QTT 代码: #include<cstdio> #include<cstring> #incl ...

  2. [BZOJ 3992] [SDOI 2015] 序列统计(DP+原根+NTT)

    [BZOJ 3992] [SDOI 2015] 序列统计(DP+原根+NTT) 题面 小C有一个集合S,里面的元素都是小于质数M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数 ...

  3. [BZOJ 3791] 作业 【DP】

    题目链接:BZOJ - 3791 题目分析 一个性质:将一个序列染色 k 次,每次染连续的一段,最多将序列染成 2k-1 段不同的颜色. 那么就可以 DP 了,f[i][j][0|1] 表示到第 i ...

  4. BZOJ 1251 序列终结者(Splay)

    题目大意 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术 ...

  5. [bzoj]2962序列操作

    [bzoj]2962序列操作 标签: 线段树 题目链接 题意 给你一串序列,要你维护三个操作: 1.区间加法 2.区间取相反数 3.区间内任意选k个数相乘的积 题解 第三个操作看起来一脸懵逼啊. 其实 ...

  6. BZOJ 5306 [HAOI2018] 染色

    BZOJ 5306 [HAOI2018] 染色 首先,求出$N$个位置,出现次数恰好为$S$的颜色至少有$K$种. 方案数显然为$a_i=\frac{n!\times (m-i)^{m-i\times ...

  7. bzoj 1858 序列操作

    bzoj 1858 序列操作 带有随机多个区间单值覆盖的区间操作题,可考虑用珂朵莉树解决. #include<bits/stdc++.h> using namespace std; #de ...

  8. codevs 1962 马棚问题--序列型DP

    1962 马棚问题  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 每天,小明和他的马外出,然后他们一边跑一边玩耍.当他们结束 ...

  9. Educational Codeforces Round 62 (Rated for Div. 2)E(染色DP,构造,思维,组合数学)

    #include<bits/stdc++.h>using namespace std;const long long mod=998244353;long long f[200007][2 ...

随机推荐

  1. Mac osx下成功安装tensorflow

    安装tensorflow有多种方式:Pip, Docker, Virtualenv, Anaconda 或 源码编译的方法安装. 我是在pip下成功安装tensorflow,以下只介绍在pip下安装( ...

  2. Spark Scala语言学习系列之完成HelloWorld程序(三种方式)

    三种方式完成HelloWorld程序 分别采用在REPL,命令行(scala脚本)和Eclipse下运行hello world. 一.Scala REPL. windows下安装好scala后,直接C ...

  3. 你必须知道的.net导航

    http://www.cnblogs.com/anytao/archive/2007/09/14/must_net_catalog.html

  4. MATLAB 2018a 下载安装

    参考链接:https://www.youtube.com/watch?v=BJavEE9KIlY

  5. AVD的Hardware选项

    最近学习开发游戏,需要GLES2.0使用,使用Android虚拟机调试一直报错闪退.百度说Android 4.0及以后的版本[使用API15及以上]),已经支持GLES2.0,需要在HardWare选 ...

  6. java线程入门知识

    为什么需要多线程? . 模型的简化,如某些程序是由多个相对独立任务的运行: . 图形界面的出现,输入.输出的阻塞 . 多核CPU的更好利用 . 异步行为的需要 Java多线程的特性: . 程序的入口m ...

  7. (转)RabbitMQ学习之spring整合发送异步消息(注解实现)

    http://blog.csdn.net/zhu_tianwei/article/details/40919249 实现使用Exchange类型为DirectExchange. routingkey的 ...

  8. js 获取 下拉框的值

    //错误 console.log($("#DictID").select.val()); //错误 console.log($("#DictID").selec ...

  9. Flask框架函数

    title: flask学习笔记 subtitle: 1. flask框架函数 date: 2018-12-14 10:17:28 --- Flask学习 学习Miguel Grinberg的2017 ...

  10. CentOS 7 yum 安装redis(更简单)

    一.安装redis 1.检查是否有redis yum 源 1 yum install redis 2.下载fedora的epel仓库 1 yum install epel-release 3.安装re ...