結果
| 問題 |
No.174 カードゲーム(Hard)
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2015-03-27 03:04:18 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 167 ms / 2,000 ms |
| コード長 | 2,160 bytes |
| コンパイル時間 | 1,172 ms |
| コンパイル使用メモリ | 164,996 KB |
| 実行使用メモリ | 25,624 KB |
| 最終ジャッジ日時 | 2024-07-06 21:33:32 |
| 合計ジャッジ時間 | 3,016 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 12 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> VI;
typedef vector<VI> VVI;
#define REP(i, n) for(int(i)=0;(i)<(n);++(i))
#define FOR(i, f, t) for(int(i)=(f);(i)<(t);(++i))
#define EACH(it, c) for(auto it=(c).begin();it!=(c).end();++it)
int N;
double P[2];
int a[22],b[22];
int res = 0;
double p[2][1<<21]; // p[a/b][使用済みカード状態ビット] = 確率
double q[2][22][22]; // q[a/b][i番目のカードを][j回目に出す] = 確率
VI pc[22];
int main(){
do { cin.tie(0); ios_base::sync_with_stdio(false); } while(0);
cin >> N >> P[0] >> P[1];
REP(i,N) cin >> a[i]; sort(a,a+N);
REP(i,N) cin >> b[i]; sort(b,b+N);
REP(i,1<<N) pc[__builtin_popcount(i)].push_back(i);
p[0][0] = p[1][0] = 1;
REP(t,2) REP(i,N){
EACH(it,pc[i]){
const int &j = *it;
bool first = true;
REP(k,N){
if((j>>k)&1) continue;
if(i < N-1){
if(first){
first = false;
double pp = p[t][j] * P[t]; // 最小値が選ばれる確率
p[t][j|(1<<k)] += pp;
q[t][k][i] += pp;
} else {
double pp = p[t][j] * (1-P[t])/(N-i-1); // (残り枚数-1)で割る
p[t][j|(1<<k)] += pp;
q[t][k][i] += pp;
}
} else {
// 最後のカード(無条件で選ぶ)
double pp = p[t][j];
p[t][j|(1<<k)] += pp;
q[t][k][i] += pp;
}
}
}
}
double res = 0;
REP(i,N){ // i枚目
REP(ai,N){ // Aが出すカード
REP(bi,N){ // Bが出すカード
if(a[ai] > b[bi]){
int score = a[ai]+b[bi];
res += score * q[0][ai][i] * q[1][bi][i];
}
}
}
}
cout << fixed << setprecision(15) << res << endl;
return 0;
}