这个题的难度都在读题。
描述得非常绕。。
看懂了就会做了。
有一个长度为C的序列,通过将W变成R、G、B 使得序列满足以下的条件
将变化后的序列中的B去掉。
剩下的R、G的数量为2*M的倍数。
将其分成M个不想交的子序列,每个长度为2*D,使得每个子序列都是RGRGRG。。。。
求方案数。
两个要控制的地方
1、RG的数量
2、序列的任意前缀都不允许R的数量多余G超过M个
F[i][j][k]表示前i个,R与G的差为j-1(防止负数),R与G的和模M为K的方案数。
ANS = F[C][1][0];
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// BEGIN CUT HERE // END CUT HERE #line 5 "AlternativePiles.cpp" #include <cstdlib> #include <cctype> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <string> #include <iostream> #include <sstream> #include <map> #include <set> #include <queue> #include <stack> #include <ctime> using namespace std; typedef long long ll; typedef pair<int,int> pii; typedef vector<int>::iterator iter; const int MAXN = 5010; int F[MAXN][60][110]; const int MOD = 1000000007; class AlternativePiles{ public: int count(string C, int M){ memset(F,0,sizeof(F)); F[0][1][0]=1; int L = C.size(); for (int i=1;i<=L;i++){ for (int j=1;j<=M+1;j++){ for (int k=0;k<2*M;k++){ if (C[i-1]=='R') F[i][j][k] = F[i-1][j-1][(k-1+2*M)%(2*M)]; if (C[i-1]=='G') F[i][j][k] = F[i-1][j+1][(k-1+2*M)%(2*M)]; if (C[i-1]=='B') F[i][j][k] = F[i-1][j][k]; if (C[i-1]=='W') F[i][j][k] = (F[i-1][j-1][(k-1+2*M)%(2*M)]+F[i-1][j][k])%MOD+F[i-1][j+1][(k-1+2*M)%(2*M)]; F[i][j][k]%=MOD; } } } return F[L][1][0]; } // BEGIN CUT HERE public: void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); if ((Case == -1) || (Case == 4)) test_case_4(); } private: template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); } void verify_case(int Case, const int &Expected, const int &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } } void test_case_0() { string Arg0 = "WRGWWRGW"; int Arg1 = 2; int Arg2 = 3; verify_case(0, Arg2, count(Arg0, Arg1)); } void test_case_1() { string Arg0 = "RRGG"; int Arg1 = 1; int Arg2 = 0; verify_case(1, Arg2, count(Arg0, Arg1)); } void test_case_2() { string Arg0 = "BBBB"; int Arg1 = 5; int Arg2 = 1; verify_case(2, Arg2, count(Arg0, Arg1)); } void test_case_3() { string Arg0 = "WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW"; int Arg1 = 50; int Arg2 = 265470435; verify_case(3, Arg2, count(Arg0, Arg1)); } void test_case_4() { string Arg0 = "WRWRGWWGWWWRWBWRWGWWRWBWWRGWBWGRGWWGWGRWGRWBRWBW"; int Arg1 = 7; int Arg2 = 7400348; verify_case(4, Arg2, count(Arg0, Arg1)); } // END CUT HERE }; // BEGIN CUT HERE int main(){ AlternativePiles ___test; ___test.run_test(-1); return 0; } // END CUT HERE