dp bzoj 2958 序列染色

https://www.lydsy.com/JudgeOnline/problem.php?id=2958

表示菜的不会去除重复的计算qwq

这里的状态\(f[i][j][pos]\)很强啊

主要是\(j\)是记录这位是多少

有效的防止重复计数

然后转移的时候手动的判断一下有多少转移到了下一状态

复杂度\(O(n)\)

dp这么菜怎么办..

#include <bits/stdc++.h>
#define int long long
#define fo(i, n) for(int i = 1; i <= (n); i ++)
#define out(x) cerr << #x << " = " << x << "\n"
#define type(x) __typeof((x).begin())
#define foreach(it, x) for(type(x) it = (x).begin(); it != (x).end(); ++ it)
using namespace std;
// by piano
template<typename tp> inline void read(tp &x) {
  x = 0; char c = getchar(); bool f = 0;
  for(; c < '0' || c > '9'; f |= (c == '-'), c = getchar());
  for(; c >= '0' && c <= '9'; x = (x << 3) + (x << 1) + c - '0', c = getchar());
  if(f) x = -x;
}
const int mo = 1e9 + 7;
const int N = 1e6 + 233;
int sumx[N], sumb[N], sumw[N], pw[N];
int n, K;
char str[N];
int f[3][2][N];

inline int doit(int pos, int fff) {
  if(pos < K || str[pos - K] == (fff ? 'W' : 'B')) return 0;
  int sum = (fff ? sumb[pos] - sumb[pos - K] : sumw[pos] - sumw[pos - K]);
  if(sum) return 0;
  else if(pos == K) return fff == 0 ? 1 : 0;
  else return f[fff][fff ^ 1][pos - K];
}

main(void) {
  read(n); read(K);
  scanf("%s", str + 1);
  pw[0] = 1;
  for(int i = 1; i <= n; i ++) {
    sumx[i] = sumx[i - 1] + (str[i] == 'X');
    sumb[i] = sumb[i - 1] + (str[i] == 'B');
    sumw[i] = sumw[i - 1] + (str[i] == 'W');
    pw[i] = pw[i - 1] * 2 % mo;
  }
  f[0][0][0] = 1;
  for(int i = 1; i <= n; i ++) {
    if(str[i] != 'W') {
      int tmp = doit(i, 0);
      f[0][0][i] = (f[0][0][i - 1] + f[0][1][i - 1] - tmp) % mo;
      f[1][0][i] = (f[1][0][i - 1] + f[1][1][i - 1] + tmp) % mo;
      f[2][0][i] = (f[2][0][i - 1] + f[2][1][i - 1]) % mo;
    }
    if(str[i] != 'B') {
      int tmp = doit(i, 1);
      f[0][1][i] = (f[0][0][i - 1] + f[0][1][i - 1]) % mo;
      f[1][1][i] = (f[1][0][i - 1] + f[1][1][i - 1] - tmp) % mo;
      f[2][1][i] = (f[2][0][i - 1] + f[2][1][i - 1] + tmp) % mo;
    }
  }
  int ans = (f[2][0][n] + f[2][1][n]) % mo;
  ans = (ans + mo) % mo;
  cout << ans << "\n";
}           

猜你喜欢

转载自www.cnblogs.com/foreverpiano/p/9157629.html