BZOJ:2958 序列染色 DP
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的更多相关文章
- bzoj2958: 序列染色(DP)
2958: 序列染色 题目:传送门 题解: 大难题啊(还是我太菜了) %一发大佬QTT 代码: #include<cstdio> #include<cstring> #incl ...
- [BZOJ 3992] [SDOI 2015] 序列统计(DP+原根+NTT)
[BZOJ 3992] [SDOI 2015] 序列统计(DP+原根+NTT) 题面 小C有一个集合S,里面的元素都是小于质数M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数 ...
- [BZOJ 3791] 作业 【DP】
题目链接:BZOJ - 3791 题目分析 一个性质:将一个序列染色 k 次,每次染连续的一段,最多将序列染成 2k-1 段不同的颜色. 那么就可以 DP 了,f[i][j][0|1] 表示到第 i ...
- BZOJ 1251 序列终结者(Splay)
题目大意 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术 ...
- [bzoj]2962序列操作
[bzoj]2962序列操作 标签: 线段树 题目链接 题意 给你一串序列,要你维护三个操作: 1.区间加法 2.区间取相反数 3.区间内任意选k个数相乘的积 题解 第三个操作看起来一脸懵逼啊. 其实 ...
- BZOJ 5306 [HAOI2018] 染色
BZOJ 5306 [HAOI2018] 染色 首先,求出$N$个位置,出现次数恰好为$S$的颜色至少有$K$种. 方案数显然为$a_i=\frac{n!\times (m-i)^{m-i\times ...
- bzoj 1858 序列操作
bzoj 1858 序列操作 带有随机多个区间单值覆盖的区间操作题,可考虑用珂朵莉树解决. #include<bits/stdc++.h> using namespace std; #de ...
- codevs 1962 马棚问题--序列型DP
1962 马棚问题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 每天,小明和他的马外出,然后他们一边跑一边玩耍.当他们结束 ...
- 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 ...
随机推荐
- selenium 最大化浏览器是解决浏览器和驱动不匹配的方法如下
那么要想selenium成功的操作chrome浏览器需要经历如下步骤: 1.下载ChromeDriver驱动包(下载地址: http://chromedriver.storage.googleapis ...
- 开发vue插件并发布到npm包管理工具的流程
1-10是开发流程,后面的是发布流程 1. 在Git里面…新建项目 2. 克隆项目到本地用来开发 git clone https://github.com/***/vue-prevent-brow ...
- Spark Streaming概念学习系列之SparkStreaming性能调优
SparkStreaming性能调优 合理的并行度 减少批处理所消耗时间的常见方式还有提高并行度.有以下三种方式可以提高并行度: 1.增加接收器数目 有时如果记录太多导致单台机器来不及读入并分发的话, ...
- 2.Ventuz Designer常用工具介绍
Ventuz Designer常用工具介绍 1. 打开Ventuz Designer 图1.1 2. Ventuz Designer第一个界面 图2.1 Recent Projects:最近创建的 ...
- SQL2012安装
SQL2012安装 1.打开SQL安装包,点击setup安装 2.选择安装界面,点击全新安装 3.验证通过后,点击确定 4.选择我接受,点击下一步 5.在外网环境,可进行在线更新,内网环境取消勾选产品 ...
- 普通平衡树 Splay
Code: #include<cstdio> #include<algorithm> #include<cstring> using namespace std; ...
- 【leecode】宝石与石头
给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头. S 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石. J 中的字母不重复,J 和 S中的所有字符都是字母 ...
- 路飞学城Python-Day137
django项目二 个人博客系统 github地址:https://github.com/pandaboy1123/cnblog
- 【数据分析学习】016-numpy数据结构
通常对数据的矩阵进行操作,就用numpy操作,打开txt文件 使用help()去查询文档,可以看到官方的注释 import numpy path = r'F:\数据分析专用\数据分析与机器学习\wor ...
- nginx获取经过层层代理后的客户端真实IP(使用正则匹配)
今天帮兄弟项目搞了一个获取客户端真实IP的问题,网上这种问题很多,但是对于我们的场景都不太合用,现把我的解决方案share给大家,如有问题,请及时指出. 场景: 在请求到达后端服务之前,会经过层层代理 ...