[ABC314E] Roulettes
假若 $\forall S_{i,p_i}>0$,显然可以直接 $\text{DP}$:
-
状态:$f_i$ 表示至少得 $i$ 分的期望代价。
-
转移:
$$ f_i=\min_{j=1}^n(C_j+\frac{1}{p_j}\sum_{k=1}^{p_j}f_{\max(i-S_{j,k},0)}) $$
-
答案:$f_m$
然而题目只说 $S_{i,p_i}\geq 0$,也就是说可能存在 $S_{i,p_i}=0$ 的情况。
对于一个转盘(数组) $i$,我们令 $cnt_i=\sum_{i=1}^{p_i}[S_{i,p_i}=0]$,那么这个转盘等价于一个 $C_j=C_i\times\frac{p_i}{p_i-k_i}$,且去掉了所有 $0$ 的转盘。
问题得以解决。
#include <bits/stdc++.h>
#define FL(i, a, b) for(int i = (a); i <= (b); i++)
#define FR(i, a, b) for(int i = (a); i >= (b); i--)
using namespace std;
const int N = 110;
int n, m, cnt;
double f[N], c[N], p[N];
vector<int> s[N];
int main(){
scanf("%d%d", &n, &m);
FL(i, 1, n){
scanf("%lf%lf", &c[i], &p[i]), cnt = 0;
FL(j, 1, p[i]){
int x; scanf("%d", &x), cnt += (!x);
if(x) s[i].emplace_back(x);
}
p[i] -= cnt; if(p[i]) c[i] *= (p[i] + cnt) / p[i];
}
FL(i, 1, m) f[i] = 1e18;
FL(i, 1, m){
FL(j, 1, n) if(p[j]){
double cost = c[j];
for(int &x: s[j])
cost += f[max(0, i - x)] / p[j];
f[i] = min(f[i], cost);
}
}
printf("%lf", f[m]);
return 0;
}