[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;
}
posted @ 2023-08-18 11:28  徐子洋  阅读(7)  评论(0)    收藏  举报  来源