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;
    }
    
    
  • 相关阅读:
    面向对象的设计模式2
    数据结构
    算法题目1
    5.7(1) 反射
    hashMap原理(java8)
    6.1 接口
    18.1 线程
    13.2 具体的集合
    scrapy(2)——scrapy爬取新浪微博(单机版)
    5.1 类、超类和子类
  • 原文地址:https://www.cnblogs.com/KirinSB/p/11342107.html
Copyright © 2011-2022 走看看