一眼想到是DP,然而不会。
用DP[i][j][k]表示第i位为k,状态为j的方案数,O(1)转移即可。Orz lych
#include<iostream>
#include<cstdio>
#define N 1000005
#define P 1000000007
using namespace std;
int n,k,dp[N][3][2],W[N],B[N],t;char c[N];
int Mo(int x,int y)
{
if (x>=P) x-=P;x+=y;
if (x>=P) return x-P;
if (x<0) return x+P;
return x;
}
int main()
{
scanf("%d%d%s",&n,&k,c+1);
dp[0][0][1]=1;
for (int i=1;i<=n;i++)
{
W[i]=W[i-1]+(c[i]=='W');
B[i]=B[i-1]+(c[i]=='B');
if (c[i]!='W')
{
if (i>=k&&W[i]==W[i-k])t=dp[i-k][0][1];else t=0;
dp[i][0][0]=Mo(dp[i-1][0][0]+dp[i-1][0][1],-t);
dp[i][1][0]=Mo(dp[i-1][1][0]+dp[i-1][1][1],+t);
dp[i][2][0]=Mo(dp[i-1][2][0]+dp[i-1][2][1],0);
}
if (c[i]!='B')
{
if (i>=k&&B[i]==B[i-k])t=dp[i-k][1][0];else t=0;
dp[i][0][1]=Mo(dp[i-1][0][0]+dp[i-1][0][1],0);
dp[i][1][1]=Mo(dp[i-1][1][0]+dp[i-1][1][1],-t);
dp[i][2][1]=Mo(dp[i-1][2][0]+dp[i-1][2][1],+t);
}
}
printf("%d\n",Mo(dp[n][2][0]+dp[n][2][1],0));
return 0;
}