zoukankan      html  css  js  c++  java
  • 杭电多校HDU 6656 Kejin Player(概率DP)题解

    题意:

    最低等级(level 1),已知在(level i)操作一次需花费(a_i),有概率(p_i)升级到(level i+1),有(1 - p_i)掉级到(x_i(x_i <= i)),询问(q)次,问你每次从(l)升级到(r)的花费的期望。

    思路:

    我们设(dp[i])为从(1)升级到(i)的期望花费,那么显然有从(l)升级到(r)的期望花费为(dp[r] - dp[l])
    然后我们可以知道,升级到(i)有两种情况:
    已经花费了(dp[i-1])必加。从(i-1)升级,那么花费(a_{i-1});掉级到(x_{i-1})再升到(i),那么花费(a_{i-1} + dp[i]-dp[x_{i-1}]),那么可以列出方程:

    [dp[i] = dp[i -1] + p_{i-1}*a_{i-1} + (1-p_{i-1})*(dp[i]-dp[x_{i-1}]+a_{i-1}) ]

    化简后可得正解。

    代码:

    #include<map>
    #include<set>
    #include<queue>
    #include<cmath>
    #include<stack>
    #include<ctime>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<sstream>
    #include<iostream>
    #include<algorithm>
    typedef long long ll;
    typedef unsigned long long ull;
    using namespace std;
    const int maxn = 5e5 + 5;
    const ll MOD = 1e9+7;
    const ull seed = 13131;
    const int INF = 998244353;
    ll dp[maxn];
    ll r[maxn], s[maxn], x[maxn], a[maxn];
    ll ppow(ll a, ll b){
        ll ret = 1;
        while(b){
            if(b & 1) ret = ret * a % MOD;
            b >>= 1;
            a = a * a % MOD;
        }
        return ret;
    }
    int main(){
        int T;
        scanf("%d", &T);
        while(T--){
            int n, q;
            scanf("%d%d", &n, &q);
            for(int i = 1; i <= n; i++){
                scanf("%lld%lld%lld%lld", &r[i], &s[i], &x[i], &a[i]);
            }
            dp[1] = 0;
            for(int i = 2; i <= n + 1; i++){
                ll inv = ppow(r[i - 1], MOD - 2);
                ll tmp1 = ((s[i - 1] * inv % MOD) * dp[i - 1] + a[i - 1]) % MOD;
                ll tmp2 = ((s[i - 1] - r[i - 1]) * inv % MOD) * dp[x[i - 1]] % MOD;
                ll tmp3 = ((s[i - 1] - r[i - 1]) * inv % MOD) * a[i - 1] % MOD;
                dp[i] = ((tmp1 - tmp2) % MOD + tmp3) % MOD;
                dp[i] = (dp[i] % MOD + MOD) % MOD;
            }
    //        for(int i = 1; i <= n + 1; i++) printf("%lld
    ", dp[i]);
            while(q--){
                int l, r;
                scanf("%d%d", &l, &r);
                ll ans = dp[r] - dp[l];
                ans = (ans % MOD + MOD) % MOD;
                printf("%lld
    ", ans);
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    灵魂拷问!浏览器输入「xxxxhub」的背后.....
    趣谈 DHCP 协议,有点意思。
    规约模式,颤抖吧产品经理!再也不怕你乱改需求了
    订阅者模式,公众号、B站、快手用了都说好!
    设计模式,你相信吗,只用两个函数实现事务!
    Linux系统中安装Jenkins
    Linux系统在线安装和查看git版本
    VIM中的保存和退出命令
    @JsonProperty爆红
    手动运行jar包
  • 原文地址:https://www.cnblogs.com/KirinSB/p/11342107.html
Copyright © 2011-2022 走看看