hdu多校第七场 1011 (hdu6656) Kejin Player 概率dp

题意:

一个游戏,有许多关,到下一关要花费金钱,做出尝试,有概率成功,若成功则到达下一关,若失败则停在此关或退回到前面某关,询问第l关到第r关的期望费用

题解:

显然,第r关到第l关的费用是dp[r]-dp[l]

那么如何算出dp数组呢?首先dp[1]=0,利用期望方程正推

假设i点,成功率为p,失败则跳到j,成功则跳到k,花费q,则期望方程为

dp[k]=dp[i]+p(q)+(1-p)(dp[k]-dp[j])

移项后递推即可

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef long long ll;
typedef pair<int, LL>P;
const int M = 4e5 * 4 + 5;
const LL mod = 1e9 + 7;
const LL lINF = 0x3f3f3f3f3f3f3f3f;
#define ls (rt<<1)
#define rs (rt<<1|1)
LL gcd(LL a, LL b) { return b ? gcd(b, a%b) : a; }
LL quickpow(LL a, LL b, LL mod)
{
    LL res = 1;
    while (b)
    {
        if (b & 1)
            res = (res*a) % mod;
        a = (a*a) % mod;
        b >>= 1;
    }
    return res;
}
inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        x = 10 * x + ch - '0';
        ch = getchar();
    }
    return x * f;
}
inline ll readll()
{
    ll x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
    {
        x = 10 * x + ch - '0';
        ch = getchar();
    }
    return x * f;
}
int n, q;
LL r[M], s[M], x[M], a[M], dp[M];
int main()
{
    int t = read();
    while (t--)
    {
        n = readll();
        q = readll();
        for (int i = 1; i <= n; i++)
        {
            r[i] = readll();
            s[i] = readll();
            x[i] = readll();
            a[i] = readll();
        }
        dp[2] = quickpow(r[1], mod - 2, mod)*a[1] % mod*s[1] % mod;
        for (int i = 2; i <= n; i++)
        {
            LL tmp = ((a[i] + (s[i] - r[i])*quickpow(s[i], mod - 2, mod) % mod*(dp[i] - dp[x[i]] + mod) % mod) % mod) % mod*s[i] % mod * quickpow(r[i], mod - 2, mod) % mod;
            dp[i + 1] = (dp[i] + tmp) % mod;
        }
        while (q--)
        {
            int l, r;
            l = read();
            r = read();
            printf("%lld\n", (dp[r] - dp[l] + mod) % mod);
        }
    }
}

 

posted @ 2019-08-13 23:38  Isakovsky  阅读(155)  评论(0编辑  收藏  举报