bzoj2958&3269 序列染色 DP计数

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
由于方法可能很多,因此只需要输出最后的答案对10^9+7取模的结果。
Input
第一行两个正整数N,K
第二行一个长度为N的字符串S
1<=N<=106,1<=K<=106
Output
一行一个整数表示答案%(10^9+7)。

题解:
f[i][j][k]
j:0,1,2表示当前B,W都不合法,B合法,都合法
k:当前位填了B/W
如何去重(直接dp长度超过k 的可行段会加重)

  1. 对于一个可行段,只考虑最后k个(只从k - 1个位置和后k个不同转移过来)
  2. 减去一定可行却仍当成不可行在统计的方案

思考的时候去重的方法没有想到。想了30min都没有想出来,看了题解才知道。思考速度和效率都不行啊!

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define repd(i,a,b) for(int i=a;i>=b;--i)
#define rvc(i,S) for(int i=0;i<(int)S.size();++i)
#define fore(i,x) for(int i = head[x] ; i ; i = e[i].next)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define lowbit(x) (x&(-x))
using namespace std;
#define maxn 1000020

const int mod = 1e9 + 7;
int w[maxn],b[maxn],f[maxn][3][2];
int n,k;
char ch[maxn];

inline void up(int &x,int y){
	x += y;
	if ( x >= mod ) x -= mod;
	else if ( x < 0 ) x += mod;
}
int main(){
	scanf("%d %d",&n,&k);
	scanf("%s",ch + 1);
	rep(i,1,n){
		w[i] = w[i - 1] + (ch[i] == 'W');
		b[i] = b[i - 1] + (ch[i] == 'B');
	}
/*	if ( ch[1] == 'X' )
		f[1][0][0] = f[1][0][1] = 1;
	else if ( ch[1] == 'B' )
		f[1][0][0] = 1;
	else 
		f[1][0][1] = 1;	*/
	f[0][0][0] = 1;

	rep(i,1,n){
		if ( ch[i] == 'B' || ch[i] == 'X' )
			rep(j,0,2) up(f[i][j][0],f[i - 1][j][0] + f[i - 1][j][1]);
		if ( ch[i] == 'W' || ch[i] == 'X' )
			rep(j,0,2) up(f[i][j][1],f[i - 1][j][1] + f[i - 1][j][0]);
		if ( i < k ) continue;
		if ( (ch[i] == 'B' || ch[i] == 'X') && w[i] - w[i - k] == 0 ){
			up(f[i][1][0],f[i - k][0][(i == k) ? 0 : 1]);
			up(f[i][0][0],-f[i - k][0][(i == k) ? 0 : 1]);
		}
		if ( (ch[i] == 'W' || ch[i] == 'X') && b[i] - b[i - k] == 0 ){
			up(f[i][2][1],f[i - k][1][0]);
			up(f[i][1][1],-f[i - k][1][0]);
		}
	}
	printf("%d\n",(f[n][2][0] + f[n][2][1]) % mod);
}

猜你喜欢

转载自blog.csdn.net/weixin_42484877/article/details/83385249