#define _USE_MATH_DEFINES #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; /* ●解法 点数の小さい順に値を確定させていく動的計画法。 前回の点数、合計点数、連続した同じ点数の人数を状態として持つ。 ・全員が違う点数 A < B < C < D < E < F ↓ 6 * 5 * 4 * 3 * 2 * 1 通りの並べ方が存在 ・同じ点数の人が存在 A = B < C = D = E < F ↓ 6 * 5 4 * 3 * 2 ----- * --------- * 1 通り 1 * 2 1 * 2 * 3 →同じ点数の人が2人いれば2で割る、3人いればさらに3で割る、… というように計算すると最低点、最高点を状態として持つ必要がなくなる。 ●計算量 審査員が n 人、各審査員の点数を s とすると、 計算量は O((n*s)^3) となる。 */ int main() { const int n = 6; const int score = 100; const int maxScore = (n - 2) * score; vector > > dp(n, vector >(score + 1, vector(maxScore + 1, 0))); dp[0][0][0] = 1; for(int i=1; i<=n; ++i) dp[0][0][0] *= i; for(int i=0; i > > nextDp(n, vector >(score + 1, vector(maxScore + 1, 0))); for(int a=0; a 0 && b == b2) nextDp[a+1][b2][c2] += dp[a][b][c] / (a + 2); else nextDp[0][b2][c2] += dp[a][b][c]; } } } } dp.swap(nextDp); } int x1, x2; char c; cin >> x1 >> c >> x2; int x = x1 * 100 + x2; long long ans = 0; for(int a=0; a