题解:AT_abc314_e [ABC314E] Roulettes

DerRichter Lv2

题意

台轮盘。第 台轮盘( )上写有 个整数 ,每次支付 日元可以玩一次。每玩一次第 台轮盘,会等概率随机选出 之间的一个整数 ,获得 分。

每次轮盘获得的分数相互独立。

Takahashi 想要获得至少 分。Takahashi 会采取使得在获得至少 分之前所支付金额尽可能小的策略。并且,Takahashi 每次玩轮盘时,可以根据之前所有轮盘的结果选择下一次要玩的轮盘。

请计算 Takahashi 在获得至少 分之前所支付金额的期望值。

思路

首先显然不是贪心。我们可以想象成,每次得到 内的任意一个整数,花费 代价,可以转换成完全背包。

发现正推似乎不太好做。所以我们倒退。设计状态 表示当前离 还有 点积分时的代价期望最小值,显然有

考虑转移,我们可以写出转移式:

但是存在 ,无法直接做。可以通过数学手段证明其绝对收敛(不写证明过程了,但确实可行),所以可以将其视为方程来看。最终转移式如下:

其中

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <bits/extc++.h>

using namespace std;
using ll = long long;
using ld = long double;

const int MAXN = 1e2 + 10;
const ll INF = 2e18;

struct Roulette {
int c, p, cnt;
vector<int> s;
} a[MAXN];

int n, m;
ld dp[MAXN << 1];

int main() {
ios::sync_with_stdio(0), cin.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i].c >> a[i].p;
a[i].s.assign(a[i].p + 5, 0);
for (int j = 1; j <= a[i].p; j++) {
cin >> a[i].s[j];
a[i].cnt += !a[i].s[j];
}
}
for (int i = m - 1; i >= 0; i--) {
dp[i] = INF;
for (int j = 1; j <= n; j++) {
ld sum = a[j].p * a[j].c;
for (int k = 1; k <= a[j].p; k++) {
if (!a[j].s[k]) continue;
sum += dp[i + a[j].s[k]];
}
dp[i] = min(dp[i], sum / (a[j].p - a[j].cnt));
}
}
cout << fixed << setprecision(50) << dp[0];
return 0;
}
  • 标题: 题解:AT_abc314_e [ABC314E] Roulettes
  • 作者: DerRichter
  • 创建于 : 2026-08-15 00:01:33
  • 更新于 : 2026-08-15 07:16:04
  • 链接: https://derrichter.onrender.com/2026/08/15/题解:AT-abc314-e-ABC314E-Roulettes/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
目录
题解:AT_abc314_e [ABC314E] Roulettes