• 【HDOJ】4652 Dice


    1. 题目描述
    对于m面的骰子。有两种查询,查询0表示求最后n次摇骰子点数相同的期望;查询1表示最后n次摇骰子点数均不相同的期望。

    2. 基本思路
    由期望DP推导,求得最终表达式。
    (1) 查询0
        不妨设$dp[k]$表示当前已经有k次相同而最终实现n次相同的期望。
        egin{align}
            dp[0] &= 1 + dp[1]  otag \
            dp[1] &= 1 + frac{1}{m}dp[2] + frac{m-1}{m}dp[1]  otag \
            dp[2] &= 1 + frac{1}{m}dp[3] + frac{m-1}{m}dp[1]  otag  \
                  &cdots       otag \
            dp[n-1] &= 1 + frac{1}{m}dp[n] + frac{m-1}{m}dp[1] otag \
            dp[n] &= 0
        end{align}
        两两相减可得。
        egin{align}
            dp[0]-dp[1] &= frac{1}{m}(dp[1]-dp[2]) otag \
            dp[1]-dp[2] &= frac{1}{m}(dp[2]-dp[3]) otag \
            dp[2]-dp[3] &= frac{1}{m}(dp[3]-dp[4]) otag \
                        &cdots otag \
            dp[n-2]-dp[n-1] &= frac{1}{m}(dp[n-1]-dp[n])
        end{align}
        由$dp[0]=1+dp[1], dp[0]-dp[1]=1$代入可得。
        egin{align}
            dp[0]-dp[1] &= 1 otag \
            dp[1]-dp[2] &= m otag \
            dp[2]-dp[3] &= m^2 otag \
                        &cdots otag \
            dp[n-1]-dp[n] &= m^{n-1}
        end{align}
        显然是一个等比数列,累加后可得$dp[0]-dp[n]=dp[0]$.
        egin{align}   
            dp[0] = frac{m^n-1}{m-1}
        end{align}

    (2)查询1
        不妨设$dp[k]$表示当前已经有k个不同而最终实现n个不同的期望。
        egin{align}
            dp[0] &= 1 + dp[1] otag \
            dp[1] &= 1 + frac{1}{m}dp[1] + frac{m-1}{m}dp[2] otag \
            dp[2] &= 1 + frac{1}{m}dp[1] + frac{1}{m}dp[2] + frac{m-2}{m}dp[3] otag \
                    &cdots otag \
            dp[n-1] &= 1 + Sigma_{i=1}^{n-1}{frac{1}{m}dp[i]} + frac{m-(n-1)}{m}dp[n] otag \
            dp[n] &= 0
        end{align}
         两两相减可得。
        egin{align}
            dp[0]-dp[1] &= frac{m-1}{m}(dp[1]-dp[2]) otag \
            dp[1]-dp[2] &= frac{m-2}{m}(dp[2]-dp[3]) otag \
                        &cdots otag \
            dp[n-2]-dp[n-1] &= frac{m-(n-1)}{m}(dp[n-1]-dp[n])
        end{align}
        由$dp[0]=1+dp[1], dp[0]-dp[1]=1$代入累加后可得。
        egin{align}
            dp[0] = Sigma_{i=1}^{n} frac{m^i}{prod_{j=0}^{i-1}(m-j)}
        end{align}

    3. 代码

     1 /* 4652 */
     2 #include <iostream>
     3 #include <sstream>
     4 #include <string>
     5 #include <map>
     6 #include <queue>
     7 #include <set>
     8 #include <stack>
     9 #include <vector>
    10 #include <deque>
    11 #include <bitset>
    12 #include <algorithm>
    13 #include <cstdio>
    14 #include <cmath>
    15 #include <ctime>
    16 #include <cstring>
    17 #include <climits>
    18 #include <cctype>
    19 #include <cassert>
    20 #include <functional>
    21 #include <iterator>
    22 #include <iomanip>
    23 using namespace std;
    24 //#pragma comment(linker,"/STACK:102400000,1024000")
    25 
    26 #define sti                set<int>
    27 #define stpii            set<pair<int, int> >
    28 #define mpii            map<int,int>
    29 #define vi                vector<int>
    30 #define pii                pair<int,int>
    31 #define vpii            vector<pair<int,int> >
    32 #define rep(i, a, n)     for (int i=a;i<n;++i)
    33 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
    34 #define clr                clear
    35 #define pb                 push_back
    36 #define mp                 make_pair
    37 #define fir                first
    38 #define sec                second
    39 #define all(x)             (x).begin(),(x).end()
    40 #define SZ(x)             ((int)(x).size())
    41 #define lson            l, mid, rt<<1
    42 #define rson            mid+1, r, rt<<1|1
    43 
    44 #define LL __int64
    45 
    46 int t;
    47 int op, n, m;
    48 
    49 LL Pow(LL base, int n) {
    50     LL ret = 1;
    51     
    52     while (n) {
    53         if (n & 1)
    54             ret *= base;
    55         n >>= 1;
    56         base *= base;
    57     }
    58     
    59     return ret;
    60 }
    61 
    62 void solve() {
    63     double ans = 0.0;
    64     
    65     if (op) {
    66         double tmp = 1.0;
    67         rep(i, 0, n) {
    68             tmp = tmp * m / (m-i);
    69             ans += tmp;
    70         }
    71     } else {
    72         LL fz = Pow(m, n) - 1;
    73         ans = fz / (m-1);
    74     }
    75     printf("%.9lf
    ", ans);
    76 }
    77 
    78 int main() {
    79     ios::sync_with_stdio(false);
    80     #ifndef ONLINE_JUDGE
    81         freopen("data.in", "r", stdin);
    82         freopen("data.out", "w", stdout);
    83     #endif
    84     
    85     while (scanf("%d", &t)!=EOF) {
    86         while (t--) {
    87             scanf("%d%d%d", &op, &m, &n);
    88             solve();
    89         }
    90     }
    91     
    92     #ifndef ONLINE_JUDGE
    93         printf("time = %d.
    ", (int)clock());
    94     #endif
    95     
    96     return 0;
    97 }
  • 相关阅读:
    软件工程结对作业
    软件工程第二次作业
    软件工程第一次作业
    MATLAB安装教程
    实现生成小学四则运算练习题
    结对编程-审查代码
    软件第三次作业
    练习使用Eclipse进行单元测试
    软件工程第一次作业
    Visual Studio Code (vscode)
  • 原文地址:https://www.cnblogs.com/bombe1013/p/5234515.html
Copyright © 2020-2023  润新知