HDU 6656 Kejin Player 概率(期望)dp

该博客介绍了如何解决一个关于武器升级概率DP问题的算法。问题涉及计算从某一级升到下一级的期望花费,并处理多次询问。通过定义期望花费的递推公式,可以实现O(1)时间复杂度回答询问。博主讨论了递推式和如何处理可能的负数和分母为0的情况。
摘要由CSDN通过智能技术生成

题意: 一个武器共有n+1级, 给出第i级升到i+1级的花费, 成功概率, 失败掉回第几级, 给出q次询问, 每次问从第l级升到第r级的期望花费.

可以发现这个题的期望具有可加性: 设 d p [ i ] dp[i] dp[i]表示 i i i升到 i + 1 i+1 i+1的期望花费, 那么 i i i升到 i + 2 i+2 i+2的花费就是 d p [ i ] + d p [ i + 1 ] dp[i]+dp[i+1] dp[i]+dp[i+1], 那么对于任意 l l l r r r只要求出 d p dp dp数组的前缀和即可 O ( 1 ) O(1) O(1)回答询问.

那么问题就转化为求 d p [ i ] dp[i] dp[i], 即每级的期望花费.
如果第j次升级成功, 那么花费就是a[i]; 如果第j次没有成功, 就要再从x[i]级升回i级, 然后再判断第j+1次有没有成功…
列个式子的话是这样: 期望花费=a[i]+(1-p[i])*(期望x[i] to i)*(a[i]+(1-p[i])*(期望x[i] to i)*…)
很显然加粗部分是递归的. 只要设期望花费为W, 加粗部分也会是W, 移一下项就能得到递推式.
d p [ i ] = ( a [ i ] + ( 1 − p [ i ] ) ∗ ( s u m [ i − 1 ] − s u m [ x [ i ] − 1 ] ) ) p [ i ] dp[i]=(\frac{a[i]+(1-p[i])*(sum[i-1]-sum[x[i]-1]))}{p[i]} dp[i]=(p[i]a[i]+(1p[i])(sum[i1]sum[x[i]1])), 其中, s u m [ j ] sum[j] sum[j]表示 d p [ j ] dp[j] dp[j]的前缀和, 即从 1 1 1级升到 j + 1 j+1 j+1级的期望花费.

注意加法取模可以不用 % m o d \%mod %mod,因为两个小于 m o d mod mod的数相加对 m o d mod mod取余只需要减掉一个 m o d mod mod就可以了(这样比较快).

这个题我用分数写不知道为啥会出现负数和分母为0的情况…

int n, q, x[M];
ll a[M], p[M], sum[M], dp[M];

inline ll MOD1(ll xx) {
    if (xx >= mod)return xx - mod;
    return xx;
}

void init() {
    int _ = read();
    while (_--) {
        n = read(), q = read();
        for (int i = 1; i <= n; ++i) {
            ll r = read(), s = read();
            x[i] = read(), a[i] = read();
            p[i] = r * niYuan(s, mod) % mod;
            dp[i] = MOD1(a[i] + MOD1(1 + mod - p[i]) * (MOD1(sum[i - 1] + mod - sum[x[i] - 1])) % mod)
                    * niYuan(p[i], mod) % mod;
            // 相当于
            // dp[i] = (a[i] + (1 - p[i]) * (sum[i - 1] - sum[x[i] - 1])) / p[i];
            sum[i] = MOD1(sum[i - 1] + dp[i]);
        }
        while (q--) {
            int l = read(), r = read();
            write(MOD1(sum[r - 1] + mod - sum[l - 1]));
            enter;
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值