結果

問題 No.174 カードゲーム(Hard)
ユーザー darisdaris
提出日時 2023-08-24 23:49:38
言語 C++23
(gcc 12.3.0 + boost 1.83.0)
結果
MLE  
実行時間 -
コード長 11,933 bytes
コンパイル時間 4,067 ms
コンパイル使用メモリ 266,548 KB
実行使用メモリ 814,624 KB
最終ジャッジ日時 2023-08-24 23:49:46
合計ジャッジ時間 6,429 ms
ジャッジサーバーID
(参考情報)
judge14 / judge15
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
4,380 KB
testcase_01 AC 1 ms
4,380 KB
testcase_02 MLE -
testcase_03 -- -
testcase_04 -- -
testcase_05 -- -
testcase_06 -- -
testcase_07 -- -
testcase_08 -- -
testcase_09 -- -
testcase_10 -- -
testcase_11 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

#ifdef INCLUDED_MAIN

int main() {
	charm();

	int n;
	vd p(2);
	cin >> n >> p;
	vvi cards(2, vi(n));
	cin >> cards;
	sort(all(cards[0]));
	sort(all(cards[1]));

	int N = 1 << n;
	// rec[x][i][step]:xがカードiをstepターン目にだす確率
	vector rec(2, vvd(N, vd(N)));
	rep(x, 0, 2) {
		vd dp(N);
		dp[N - 1] = 1;
		rrep(bit, N, -1) {
			bool fst = true;
			rep(i, 0, n) {
				if (bit & (1 << i)) {
					// 何かカードを1枚だした
					int nbit = bit ^ (1 << i);
					// 手札の数
					int cnt = __builtin_popcount(bit);
					// 何試合目か
					int step = n - cnt;
					// 1枚しか持ってないとき
					if (cnt == 1) {
						rec[x][i][step] += dp[bit];
						dp[nbit] += dp[bit];
					}
					// 複数枚もってるとき
					else {
						// 事前にカードはソートしてあるので最初のが最小
						double prob = (fst ? p[x] : (1 - p[x]) / (cnt - 1));
						rec[x][i][step] += dp[bit] * prob;
						dp[nbit] += dp[bit] * prob;
						fst = false;
					}
				}
			}
		}
	}

	double ans = 0;
	rep(step, 0, n) {
		rep(i, 0, n) {
			rep(j, 0, n) {
				if (cards[0][i] < cards[1][j]) continue;
				ans += (cards[0][i] + cards[1][j]) * rec[0][i][step] * rec[1][j][step];
			}
		}
	}
	print(ans);



	return 0;
}
/* 
 * dp[SA][SB]は無理
 * A, Bのカードを出すルールは独立(相手の状態に依らない)
 * dp[SX]:X(A or B)がもっているカードがSXである確率
 * -> Xが何試合目にどのカードを出すかの確率が全部わかる
 */

#else
//#define _GLIBCXX_DEBUG
//#include "typename.hpp"
#include "bits/stdc++.h"

#define overload4(_1, _2, _3, _4, name, ...) name
#define each1(i, a) for (auto&& i : a)
#define each2(i, j, a) for (auto&& [i, j] : a)
#define each3(i, j, k, a) for (auto&& [i, j, k] : a)
#define each(...) overload4(__VA_ARGS__, each3, each2, each1)(__VA_ARGS__)
#define all1(v) (v).begin(), (v).end()
#define all2(v, b) (v).begin(), (v).begin() + b
#define all3(v, a, b) (v).begin() + a, (v).begin() + b
#define all4(v, a, b, c) (v).begin() + a, (v).begin() + b, c
#define all(...) overload4(__VA_ARGS__, all4, all3, all2, all1)(__VA_ARGS__)
#define rall(v) (v).rbegin(), (v).rend()
#define rep(i, j, n) for (ll i = j; i < (ll)(n); i++)
#define rrep(i, j, n) for (ll i = j; i > (ll)(n); i--)

using namespace std;

template<class T> using V = vector<T>;
template<class T> using VV = V<V<T>>;
//template<class T, class Ta> using P = pair<T, Ta>;
template<class T> using PQ = priority_queue<T>;
template<class T> using PQgre = priority_queue<T, V<T>, greater<T>>;

using ll = long long;
using ld = long double;
//using LL = __int128;
using pii = pair<int, int>;
using psi = pair<string, int>;
using pll = pair<ll, ll>;
using pil = pair<int, ll>;
using pli = pair<ll, int>;
using vb = V<bool>;
using vi = V<int>;
using vd = V<double>;
using vc = V<char>;
using vs = V<string>;
using vvb = V<vb>;
using vll = V<ll>;
using vld = V<ld>;
using vvi = V<vi>;
using vvd = V<vd>;
using vvll = V<vll>;
using vvld = V<vld>;
using vvc = V<vc>;
using vpii = V<pii>;
using vpll = V<pll>;
using vpil = V<pil>;
using vpli = V<pli>;

const int inf = 1ll << 30;
const ll infl = 1ll << 60;
const double pi = acos(-1.0);
const int mod1 = 998244353;
const int mod2 = 1000000007;
const int mod3 = 1000000009;
const vector<int> dx = { 1, 1, 0, -1, -1, -1, 0, 1 };
const vector<int> dy = { 0, 1, 1, 1, 0, -1, -1, -1 };
//const vector<pair<int, int>> delta = { { 1, 0 }, { 1, 1 }, { 0, 1 }, { -1, 1 }, { -1, 0 }, { -1, -1 }, { 0, -1 }, { 1, -1 } };

// prototype
template<typename T, typename Ta> istream& operator>>(istream& is, pair<T, Ta>& p);
template<typename T> istream& operator>>(istream& is, vector<T>& v);
template<typename T> istream& operator>>(istream& is, vector<vector<T>>& v);
//istream& operator>>(istream& is, __int128& x);
template<class T> void input(T& a);
template<class T, class... Ts> void input(T& a, Ts&... b);

template<typename T, typename Ta> istream& operator>>(istream& is, pair<T, Ta>& p) {
	is >> p.first >> p.second;
	return is;
}
template<typename T> istream& operator>>(istream& is, vector<T>& v) {
	for (auto&& c : v) is >> c;
	return is;
}
template<typename T> istream& operator>>(istream& is, vector<vector<T>>& v) {
	for (auto&& c : v) is >> c;
	return is;
}
/*
istream& operator>>(istream& is, __int128& x) {
  x = 0;
  string s;
  is >> s;
  bool res = s[0] == '-';
  for (size_t i = (res ? 1 : 0); i < s.size(); i++) {
	x *= 10;
	x += s[i] - '0';
  }
  if (res) x = -x;
  return is;
}
*/
template<class T> void input(T& a) {
	cin >> a;
}
template<class T, class... Ts> void input(T& a, Ts&... b) {
	cin >> a;
	input(b...);
}

// prototype
template<typename T, typename Ta> ostream& operator<<(ostream& os, const pair<T, Ta>& p);
template<typename T> ostream& operator<<(ostream& os, const vector<T>& v);
template<typename T> ostream& operator<<(ostream& os, const vector<vector<T>>& v);
template<typename T, typename Ta> ostream& operator<<(ostream& os, const map<T, Ta>& mp);
template<typename T> ostream& operator<<(ostream& os, const set<T>& s);
template<typename T> ostream& operator<<(ostream& os, const multiset<T>& ms);
template<typename T, size_t... index> void printTuple(ostream& os, const T& tp, index_sequence<index...>, size_t n);
template<typename T> void forTuple(ostream& os, const T& tp);
template<typename ...T> ostream& operator<<(ostream& os, const tuple<T...>& tp);
//ostream& operator<<(ostream& os, const __int128& x);
void print();
template<class T> void print(const T& a);
template<class T, class... Ts> void print(const T& a, const Ts&... b);

template<typename T, typename Ta> ostream& operator<<(ostream& os, const pair<T, Ta>& p) {
	os << "{ " << p.first << ", " << p.second << " }";
	return os;
}
template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) {
	os << "[ ";
	for (size_t i = 0; i < v.size(); i++) {
		os << v[i] << (i == v.size() - 1 ? "" : ", ");
	}
	return os << " ]";
}
template<typename T> ostream& operator<<(ostream& os, const vector<vector<T>>& v) {
	os << "[\n";
	for (size_t i = 0; i < v.size(); i++) {
		os << "[ ";
		for (size_t j = 0; j < v[i].size(); j++) {
			os << v[i][j] << (j == v[i].size() - 1 ? "" : ", ");
		}
		os << " ]";
		os << (i == v.size() - 1 ? "" : "\n");
	}
	return os << "\n]";
}
template<typename T, typename Ta>
ostream& operator<<(ostream& os, const map<T, Ta>& mp) {
	os << "{ ";
	auto it = mp.begin();
	while (it != mp.end()) {
		os << (it == mp.begin() ? "" : ", ") << *it;
		it++;
	}
	return os << " }";
}
template<typename T> ostream& operator<<(ostream& os, const set<T>& s) {
	os << "{ ";
	auto itr = s.begin();
	while (itr != s.end()) {
		os << (itr == s.begin() ? "" : ", ") << *itr;
		itr++;
	}
	return os << " }";
}
template<typename T>
ostream& operator<<(ostream& os, const multiset<T>& ms) {
	os << "{ ";
	auto itr = ms.begin();
	while (itr != ms.end()) {
		os << (itr == ms.begin() ? "" : ", ") << *itr;
		itr++;
	}
	return os << " }";
}
template<typename T, size_t... index> void printTuple(ostream& os, const T& tp, index_sequence<index...>, size_t n) {
	using swallow = vector<int>;
	(void)swallow
	{
		(os << get<index>(tp) << (index == n - 1 ? "" : ", "), 0)...
	};
}
template<typename T> void forTuple(ostream& os, const T& tp) {
	constexpr size_t n = tuple_size_v<T>;
	printTuple(os, tp, make_index_sequence<n>{}, n);
}
template<typename ...T> ostream& operator<<(ostream& os, const tuple<T...>& tp) {
	os << "{ ";
	forTuple(os, tp);
	return os << " }";
}
/*
ostream& operator<<(ostream& os, const __int128& x) {
  __int128 tmp = x;
  if (tmp == 0) return os << 0;
  if (tmp < 0) {
	os << '-';
	tmp = -tmp;
  }
  vector<int> ret;
  while (tmp) {
	ret.emplace_back(tmp % 10);
	tmp /= 10;
  }
  reverse(ret.begin(), ret.end());
  for (auto&& i : ret) os << i;
  return os;
}
*/
void print() {
	cout << '\n';
}
template<class T> void print(const T& a) {
	cout << a << '\n';
}
template<class T, class... Ts> void print(const T& a, const Ts&... b) {
	cout << a; (cout << ... << (cout << ' ', b));
	cout << '\n';
	//{ cout << a << ' '; print(b...); }
}

void charm() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	cout << fixed << setprecision(15);
}

template<typename T>
bool chmax(T& a, const T b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}

template<typename T>
bool chmin(T& a, const T b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}

template<typename T>
vector<tuple<T>> zip(vector<T>& v) {
	vector<tuple<T>> vt(v.size());
	for (size_t i = 0; i < v.size(); i++) vt[i] = make_tuple(v[i]);
	return vt;
}

template<typename T, typename... Ts>
auto zip(vector<T>& v, Ts&&... vs) {
	auto vt = zip(v);
	auto vts = zip(vs...);
	size_t m = min(vt.size(), vts.size());
	auto te = decltype(vt)(1)[0];
	auto tse = decltype(vts)(1)[0];
	vector res(m, tuple_cat(te, tse));
	for (size_t i = 0; i < m; i++) res[i] = tuple_cat(vt[i], vts[i]);
	return res;
}

ll power(ll n, ll k) {
	ll res = 1;
	while (k) {
		if (k & 1) res *= n;
		n *= n;
		k >>= 1;
	}
	return res;
}

ll powerMod(ll n, ll k, ll mod) {
	ll res = 1;
	while (k) {
		if (k & 1) res = res * n % mod;
		n = n * n % mod;
		k >>= 1;
	}
	return res;
}

vector<vector<int>> graph(int n, int m, bool directed = 0, int origin = 1) {
	vector<vector<int>> g(n);
	while (m--) {
		int u, v;
		cin >> u >> v;
		u -= origin, v -= origin;
		g[u].emplace_back(v);
		if (!directed) g[v].emplace_back(u);
	}
	return g;
}

auto weightedGraph(int n, int m, bool directed = 0, int origin = 1) {
	/*struct Edge {
		int to; ll w;
		Edge(int to, ll w) : to(to), w(w) {}
	};
	vector<vector<Edge>> g(n);*/
	vector<vector<pair<int, long long>>> g(n);
	while (m--) {
		int u, v;
		ll w;
		cin >> u >> v >> w;
		u -= origin, v -= origin;
		g[u].emplace_back(v, w);
		if (!directed) g[v].emplace_back(u, w);
	}
	return g;
}

template<int mod>
struct ModInt {
	ll x;
	constexpr ModInt(ll a = 0) noexcept : x(a >= 0 ? a % mod : (a % mod + mod)) {};

	constexpr ModInt& operator+=(const ModInt& r) noexcept {
		x += r.x;
		if (x >= mod) x -= mod;
		return *this;
	}
	constexpr ModInt& operator-=(const ModInt& r) noexcept {
		x -= r.x;
		if (x < 0) x += mod;
		return *this;
	}
	constexpr ModInt& operator*=(const ModInt& r) noexcept {
		x = x * r.x % mod;
		return *this;
	}
	constexpr ModInt& operator/=(const ModInt& r) noexcept {
		return *this *= r.inverse();
	}

	constexpr ModInt operator+(const ModInt& r) const noexcept { return ModInt(*this) += r; }
	constexpr ModInt operator-(const ModInt& r) const noexcept { return ModInt(*this) -= r; }
	constexpr ModInt operator*(const ModInt& r) const noexcept { return ModInt(*this) *= r; }
	constexpr ModInt operator/(const ModInt& r) const noexcept { return ModInt(*this) /= r; }
	constexpr ModInt operator-() const noexcept { return ModInt(-x); };
	constexpr bool operator==(const ModInt& r) const noexcept { return x == r.x; }
	constexpr bool operator!=(const ModInt& r) const noexcept { return x != r.x; }
	constexpr ModInt& operator++() noexcept {
		(*this) += 1;
		return *this;
	}
	constexpr ModInt& operator--() noexcept {
		(*this) -= 1;
		return *this;
	}
	constexpr ModInt operator++(int) noexcept {
		ModInt tmp(*this);
		++(*this);
		return tmp;
	}
	constexpr ModInt operator--(int) noexcept {
		ModInt tmp(*this);
		--(*this);
		return tmp;
	}

	constexpr ModInt inverse() const noexcept {
		ll xx = 1, u = 0, s = x, t = mod;
		ll k;
		while (t) {
			k = s / t;
			swap(s -= k * t, t);
			swap(xx -= k * u, u);
		}
		return ModInt(xx);
	}

	constexpr ModInt power(ll k) const noexcept {
		ModInt res = 1, y = x;
		while (k) {
			if (k & 1) res *= y;
			y *= y;
			k >>= 1;
		}
		return res;
	}

	friend istream& operator>>(istream& is, ModInt& r) {
		ll s;
		is >> s;
		r = ModInt<mod>(s);
		return is;
	}

	friend ostream& operator<<(ostream& os, const ModInt& r) {
		return os << r.x;
	}
};
using mint = ModInt<mod1>;

#define INCLUDED_MAIN
#include __FILE__

#endif
0