BZOJ:2958 序列染色 DP
来源:互联网 发布:5s4g网络怎么设置 编辑:程序博客网 时间:2024/05/14 17:05
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<=10^6,1<=K<=10^6
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;}
- [DP] BZOJ 2958 序列染色
- BZOJ:2958 序列染色 DP
- BZOJ 2958&3269: 序列染色
- BZOJ 2958: 序列染色 && BZOJ 3193: [JLOI2013]地形生成 —— 肆虐的DP
- bzoj 2958: 序列染色 递推
- BZOJ(本校) 3048 染色 - dp&递推找规律
- BZOJ 1304 叶子的染色 树形DP
- bzoj 4033: [HAOI2015]树上染色 树形dp
- [树形DP] BZOJ 4033 [HAOI2015]树上染色
- BZOJ 4033: [HAOI2015]树上染色 树形dp
- [BZOJ]4033: [HAOI2015]树上染色 树形DP
- BZOJ 1304: [CQOI2009]叶子的染色 树形DP
- bzoj 4033: [HAOI2015]树上染色(树形DP)
- BZOJ 1304: [CQOI2009]叶子的染色 树形dp
- [树形DP]BZOJ 4033—— [HAOI2015]树上染色
- 【BZOJ】【P1046】【HAOI2007】【上升序列】【题解】【dp】
- BZOJ 1046 HAOI 2007 上升序列 DP
- 【DP】 BZOJ 3675: [Apio2014]序列分割
- 笔试题
- Linux必备命令_测试01
- Tensorflow简单复现softmax模型对于mnist数据集分类
- Jenkins pipeline中下载多个配置库
- OOA/D:面向对象分析与设计
- BZOJ:2958 序列染色 DP
- Tomcat线程池与NIO配置
- SpringMVC的@RequestParam 请求乱码
- 网线切割 解题报告
- day1
- linux设备驱动的总线,设备和驱动的关系
- Mysql慢查询之Copying to tmp table
- Python全局解释器锁
- 台式机重装系统(ubuntu16.04+win10)过程记录