メモ化する。直前の1行を覚えておけばいい。
- const int mod = 1000000007;
- const int N = 50 + 1;
- const int M = 3 + 1;
- map<string, lli> memo[N];
- bool cmp(string a, string b)
- {
- int a_pass = count(a.begin(), a.end(), 'P');
- int b_pass = count(b.begin(), b.end(), 'P');
- if (a_pass > b_pass) return true;
- int a_chal = count(a.begin(), a.end(), 'C');
- int b_chal = count(b.begin(), b.end(), 'C');
- if (a_pass == b_pass && a_chal <= b_chal) return true;
- return false;
- }
- lli rec(int n, string prev, const vector<string> &D)
- {
- if (n < 0) return 1;
- if (memo[n].count(prev)) return memo[n][prev];
- const int Y = count(D[n].begin(), D[n].end(), 'Y');
- const string s = "PCFN";
- string t = "@@@";
- lli sum = 0;
- for (int a = 0; a < s.size(); ++a) {
- if (D[n][0] == 'N' || s[a] == 'N') if (D[n][0] != s[a]) continue;
- for (int b = 0; b < s.size(); ++b) {
- if (D[n][1] == 'N' || s[b] == 'N') if (D[n][1] != s[b]) continue;
- for (int c = 0; c < s.size(); ++c) {
- if (D[n][2] == 'N' || s[c] == 'N') if (D[n][2] != s[c]) continue;
- t[0] = s[a];
- t[1] = s[b];
- t[2] = s[c];
- int pass = count(t.begin(), t.end(), 'P');
- int chal = count(t.begin(), t.end(), 'C');
- int fail = count(t.begin(), t.end(), 'F');
- if (pass + chal + fail == Y && cmp(t, prev) ) {
- sum = (sum + rec(n - 1, t, D)) % mod;
- }
- }
- }
- }
- return memo[n][prev] = sum;
- }
- class SRMSystemTestPhase {
- public:
- int countWays(vector <string> D)
- {
- fill(memo, memo + N, map<string, lli>());
- return rec((int)D.size() - 1, "CCC", D);
- }
- };
0 件のコメント :
コメントを投稿