結果
| 問題 | No.1688 Veterinarian |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-05-21 12:02:16 |
| 言語 | C++23 (gcc 15.2.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 304 ms / 3,000 ms |
| コード長 | 1,977 bytes |
| 記録 | |
| コンパイル時間 | 3,202 ms |
| コンパイル使用メモリ | 340,416 KB |
| 実行使用メモリ | 33,536 KB |
| 最終ジャッジ日時 | 2026-05-21 12:02:23 |
| 合計ジャッジ時間 | 4,763 ms |
|
ジャッジサーバーID (参考情報) |
judge1_0 / judge2_0 |
| 純コード判定待ち |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 14 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
ll A, B, C, N;
cin >> A >> B >> C >> N;
map<array<ll, 4>, array<double, 3>> memo;
auto dfs = [&](auto&& self, ll x, ll y, ll z, ll cnt) -> array<double, 3> {
array<ll, 4> key = {x, y, z, cnt};
if (memo.count(key)) return memo[key];
if (cnt == 0) {
return memo[key] = {0.0, 0.0, 0.0};
}
ll t = x + y + z;
double pa = 0.0, pb = 0.0, pc = 0.0;
if (x >= 2) pa = double(x) * (x - 1) / t / (t - 1);
if (y >= 2) pb = double(y) * (y - 1) / t / (t - 1);
if (z >= 2) pc = double(z) * (z - 1) / t / (t - 1);
double p_stay = 1.0 - pa - pb - pc;
array<double, 3> res = {0.0, 0.0, 0.0};
// 違う色を引いた場合:状態は変わらない
{
auto nxt = self(self, x, y, z, cnt - 1);
for (int i = 0; i < 3; i++) {
res[i] += p_stay * nxt[i];
}
}
// 白を2枚引いた場合
if (x >= 2) {
auto nxt = self(self, x - 1, y, z, cnt - 1);
res[0] += pa * (1.0 + nxt[0]);
res[1] += pa * nxt[1];
res[2] += pa * nxt[2];
}
// 黒を2枚引いた場合
if (y >= 2) {
auto nxt = self(self, x, y - 1, z, cnt - 1);
res[0] += pb * nxt[0];
res[1] += pb * (1.0 + nxt[1]);
res[2] += pb * nxt[2];
}
// 茶を2枚引いた場合
if (z >= 2) {
auto nxt = self(self, x, y, z - 1, cnt - 1);
res[0] += pc * nxt[0];
res[1] += pc * nxt[1];
res[2] += pc * (1.0 + nxt[2]);
}
return memo[key] = res;
};
auto ans = dfs(dfs, A, B, C, N);
cout << fixed << setprecision(10);
cout << ans[0] << " " << ans[1] << " " << ans[2] << '\n';
}