結果
| 問題 | No.174 カードゲーム(Hard) |
| コンテスト | |
| ユーザー |
Kyutatsu
|
| 提出日時 | 2025-10-16 22:44:50 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 195 ms / 2,000 ms |
| コード長 | 2,499 bytes |
| コンパイル時間 | 1,587 ms |
| コンパイル使用メモリ | 119,976 KB |
| 実行使用メモリ | 11,952 KB |
| 最終ジャッジ日時 | 2025-10-16 22:44:55 |
| 合計ジャッジ時間 | 3,991 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 12 |
ソースコード
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
using namespace std;
int main() {
int N;
double PA, PB;
cin >> N >> PA >> PB;
vector<int> A(N), B(N);
for (int i=0;i<N;i++) cin >> A[i]; ranges::sort(A);
for (int i=0;i<N;i++) cin >> B[i]; ranges::sort(B);
// A, Bの出し方は相手に依存しない。それぞれ求める.
// DP[bitカードの状態] := その状態になる確率
int siz = 1 << N;
// DPを元に、card[n試合目][カード1〜Nのうちiを出す] := 確率 を求める.
vector ca(N, vector<double>(N));
vector cb(N, vector<double>(N));
{
double P = PA;
double PI = 1.0 - P;
vector<double> DP(siz);
DP[siz-1] = 1;
for (int i=siz-1;0<=i;i--) {
bool is_first = true;
int rem = popcount((unsigned int)i);
for (int c=0;c<N;c++) {
if (i & (1<<c)) {
// まだそのカードがあるなら...
double px;
if (rem==1) {
px = DP[i] * 1.0;
} else {
double p = is_first ? P : PI/(rem-1);
px = DP[i] * p;
}
DP[i ^ (1<<c)] += px;
ca[N-rem][c] += px;
is_first = false;
}
}
}
}
{
double P = PB;
double PI = 1.0 - P;
vector<double> DP(siz);
DP[siz-1] = 1;
for (int i=siz-1;0<=i;i--) {
bool is_first = true;
int rem = popcount((unsigned int)i);
for (int c=0;c<=N;c++) {
if (i & (1<<c)) {
// まだそのカードがあるなら...
double px;
if (rem==1) {
px = DP[i] * 1.0;
} else {
double p = is_first ? P : PI/(rem-1);
px = DP[i] * p;
}
DP[i ^ (1<<c)] += px;
cb[N-rem][c] += px;
is_first = false;
}
}
}
}
double res = 0;
for (int n=0;n<N;n++)
for (int i=0;i<N;i++)
for (int j=0;j<N;j++)
if (B[j]<A[i])
res += (ca[n][i]*cb[n][j]) * (A[i]+B[j]);
cout << fixed << setprecision(12) << res << endl;
}
Kyutatsu