メモ化する。直前の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 件のコメント :
コメントを投稿