結果
問題 |
No.108 トリプルカードコンプ
|
ユーザー |
![]() |
提出日時 | 2025-09-15 22:16:02 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 16 ms / 5,000 ms |
コード長 | 1,139 bytes |
コンパイル時間 | 1,395 ms |
コンパイル使用メモリ | 119,368 KB |
実行使用メモリ | 11,904 KB |
最終ジャッジ日時 | 2025-09-15 22:16:05 |
合計ジャッジ時間 | 2,743 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 20 |
ソースコード
#include<iostream> #include<vector> #include<iomanip> #include<functional> using namespace std; int main() { int N; cin >> N; vector<int> A(N); for (int i=0;i<N;i++) cin >> A[i]; vector<int> cnt(4); for (int i=0;i<N;i++) cnt[min(3, A[i])]++; for (int i=3;0<i;i--) cnt[i-1] += cnt[i]; // DP[1枚以上][2枚以上][3枚以上] := コンプまでの回数期待値 vector DP(N+1, vector(N+1, vector(N+1, -1.0))); function<double(int,int,int)> dfs = [&](int n1, int n2, int n3) { if (DP[n1][n2][n3]!=-1.0) return DP[n1][n2][n3]; if (n3==N) return 0.0; double E = 1.0; double N0 = N-n1; if (0<N0) E += (N0 / N) * dfs(n1+1, n2, n3); double N1 = n1-n2; if (0<N1) E += (N1 / N) * dfs(n1, n2+1, n3); double N2 = n2-n3; if (0<N2) E += (N2 / N) * dfs(n1, n2, n3+1); double N3 = n3; E /= 1.0 - (N3 / N); DP[n1][n2][n3] = E; return E; }; cout << fixed << setprecision(12) << dfs(cnt[1],cnt[2],cnt[3]) << endl; }