HDU 4652 Dice:期望dp(成环)【错位相减】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4652

题意:

  给你一个有m个面的骰子。

  两种询问:

    (1)"0 m n": “最后n次点数均相同”的投掷次数期望。

    (2)"1 m n": “最后n次点数各不相同”的投掷次数期望。

题解:

  表示状态:

    dp[i] = expectation (当前已经有i个点数相同/不相同)

  找出答案:

    ans = dp[0]

  如何转移:

  一、都相同

    (1)dp[i] = dp[i+1]/m + dp[1]*(1-1/m) + 1 (要么与前面相同,要么不同)

    (2)dp[i+1] = dp[i+2]/m + dp[1]*(1-1/m) + 1 (为了错位相减消去后面的dp[1],令i = i+1)

    (1)-(2)得:

      dp[i] - dp[i+1] = (dp[i+1] - dp[i+2])/m

    设d[i] = dp[i] - dp[i+1],有d[i+1]= dp[i]*m (d[i]可递推)

    则:dp[0] - dp[n] = sigma(d[0 to n-1]) (前后两项相消)

    又因为:dp[n] = 0

    所以:dp[0] = sigma(d[0 to n-1]),枚举求和即可。

  二、都不同

    (1)dp[i] = dp[i+1]*(m-i)/m + dp[i]/m + dp[i-1]/m +...+ dp[1]/m + 1 (要么与之前均不同,要么与第n,n-1,n-2...1位相同)

    (2)dp[i+1] = dp[i+2]*(m-i-1)/m + dp[i+1]/m + dp[i]/m +...+ dp[1]/m + 1 (令i = i+1,错位相减)

    (1)-(2)得:

      dp[i] - dp[i+1] = (dp[i+1] - dp[i+2])*(m-i-1)/m

    设d[i] = dp[i] - dp[i+1],有d[i+1]= dp[i]*m/(m-i-1) (d[i]可递推)

    则:dp[0] - dp[n] = sigma(d[0 to n-1])

    同一中:dp[0] = sigma(d[0 to n-1]) 即为答案。

AC Code:

  1 // PROB 1: is the same
  2 //
  3 // state expresssion:
  4 // dp[i] = expectation
  5 // i: the same numbers
  6 //
  7 // find the answer:
  8 // ans = dp[1] + 1
  9 //
 10 // transferring:
 11 // dp[i] = dp[i+1]/m + dp[1]*(1-1/m) + 1
 12 // dp[i+1] = dp[i+2]/m + dp[1]*(1-1/m) + 1
 13 // dp[i] - dp[i+1] = dp[i+1]/m - dp[i+2]/m
 14 // dp[i] - dp[i+1] = (dp[i+1] - dp[i+2])/m
 15 // dp[i+1] - dp[i+2] = (dp[i] - dp[i+1])*m
 16 // d[0] = dp[0] - dp[1] = 1
 17 // dp[0] + dp[n] = sigma(d[0 to n-1])
 18 // dp[0] = sigma(d[0 to n-1])
 19 //
 20 //
 21 // PROB 2: is different
 22 //
 23 // state expression:
 24 // dp[i] = expectation
 25 // i: different numbers
 26 //
 27 // find the answer:
 28 // ans = dp[1] + 1
 29 //
 30 // transferring:
 31 // dp[i] = dp[i+1]*(m-i)/m + dp[i]/m + dp[i-1]/m +...+ dp[1]/m + 1
 32 // dp[i+1] = dp[i+2]*(m-i-1)/m + dp[i+1]/m + dp[i]/m +...+ dp[2]/m + dp[1]/m + 1
 33 // dp[i] - dp[i+1] = dp[i+1]*(m-i)/m - dp[i+2]*(m-i-1)/m - dp[i+1]/m
 34 // dp[i] - dp[i+1] = (dp[i+1] - dp[i+2])*(m-i-1)/m
 35 // dp[i+1] - dp[i+2] = (dp[i] - dp[i+1])*m/(m-i-1)
 36 // d[0] = dp[0] - dp[1] = 1
 37 // dp[0] + dp[n] = sigma(d[0 to n-1])
 38 // dp[0] = sigma(d[0 to n-1])
 39 #include <iostream>
 40 #include <stdio.h>
 41 #include <string.h>
 42 #define MAX_N 1000005
 43
 44 using namespace std;
 45
 46 int n,m,p,t;
 47 double ans;
 48 double dp[MAX_N];
 49
 50 void read()
 51 {
 52     cin>>p>>m>>n;
 53 }
 54
 55 void cal_dp_same()
 56 {
 57     // dp[i+1] - dp[i+2] = (dp[i] - dp[i+1])*m
 58     // dp[0] = sigma(d[0 to n-1])
 59     double d=1;
 60     ans=0;
 61     for(int i=0;i<n;i++)
 62     {
 63         ans+=d;
 64         d*=m;
 65     }
 66 }
 67
 68 void cal_dp_dif()
 69 {
 70     // dp[i+1] - dp[i+2] = (dp[i] - dp[i+1])*m/(m-i-1)
 71     // dp[0] = sigma(d[0 to n-1])
 72     double d=1;
 73     ans=0;
 74     for(int i=0;i<n;i++)
 75     {
 76         ans+=d;
 77         d*=m/(m-i-1.0);
 78     }
 79 }
 80
 81 void solve()
 82 {
 83     if(p==0) cal_dp_same();
 84     else cal_dp_dif();
 85 }
 86
 87 void print()
 88 {
 89     printf("%.9f\n",ans);
 90 }
 91
 92 int main()
 93 {
 94     while(cin>>t)
 95     {
 96         while(t--)
 97         {
 98             read();
 99             solve();
100             print();
101         }
102     }
103 }

dp[i] = dp[i+1]*(m-i)/m + dp[i]/m + dp[i-1]/m +...+ dp[1]/m + 1

时间: 2024-07-28 16:27:18

HDU 4652 Dice:期望dp(成环)【错位相减】的相关文章

hdu 4652 Dice(期望)

http://acm.hdu.edu.cn/showproblem.php?pid=4652 掷一枚骰子,有m个面,问掷出连续出现n个相同的面以及连续出现n个两两不同的面的期望. 设dp[i]表示已经掷出i个相同/不同的面的期望,可以确定终态dp[n] = 0, 对于出现连续n个相同的面有 dp[i] = 1/m * dp[i+1] + (m-1)/m*dp[1] + 1 再列一个式子 dp[i+1] = 1/m * dp[i+2] + (m-1)/m * dp[1] + 1 两式相减得dp[i

HDU 4652 Dice (概率DP)

B - Dice Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4652 Description You have a dice with m faces, each face contains a distinct number. We assume when we tossing the dice, each face will o

HDU 4652 Dice (概率DP)

Dice Problem Description You have a dice with m faces, each face contains a distinct number. We assume when we tossing the dice, each face will occur randomly and uniformly. Now you have T query to answer, each query has one of the following form: 0

错位相减求和法

前言 等比数列的前\(n\)项的求和公式的推导方法,就是错位相减求和法. 适用范围 ①等比数列[基本]: ②差比数列[拓展]:错位相减求和法适用于由等差数列\(\{a_n\}\)和等比数列\(\{b_n\}\)对应相乘得到的差比数列\(\{a_n\cdot b_n\}\):比如有题目给定一个数列\(\{\cfrac{n}{2^n}\}\),我们先将其适当变形为\(\{n\cdot (\cfrac{1}{2})^n\}\),则可以看出其第一个因子数列\(a_n=n\)就是个等差数列,第二个因子数列

HDU 4652 Dice(概率dp)

Problem Description You have a dice with m faces, each face contains a distinct number. We assume when we tossing the dice, each face will occur randomly and uniformly. Now you have T query to answer, each query has one of the following form: 0 m n:

HDU 3853 LOOPS (期望DP)

题意:给定一个 n * m的矩阵,然后你从 (1,1)到 (n,m),每次你有三种可能,不动,向右,向下,每次要消耗2个魔法,并且给定每个概率, 问你走出去的期望. 析:dp[i][j] 表示从 (i,j)到终点的概率.然后一路逆推回去就好. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <

HDU 4405 概率期望DP

有 0到 n 个格子.掷骰子走路,求出到终点的数学期望,有飞行的路线. dp[i] 存储在i位置走到终点的期望. 转移方程dp[i]=(dp[i+1] ----> dp[i+6])/6+1; 有飞行路线则直接赋值 #include "stdio.h" #include "string.h" double dp[100010]; int hash[100010]; int main() { int n,m,x,y,i,j; while (scanf("

Maze HDU - 4035(期望dp)

When wake up, lxhgww find himself in a huge maze. The maze consisted by N rooms and tunnels connecting these rooms. Each pair of rooms is connected by one and only one path. Initially, lxhgww is in room 1. Each room has a dangerous trap. When lxhgww

HDU 4599 Dice (概率DP+数学+快速幂)

题意:给定三个表达式,问你求出最小的m1,m2,满足G(m1) >= F(n), G(m2) >= G(n). 析:这个题是一个概率DP,但是并没有那么简单,运算过程很麻烦. 先分析F(n),这个用DP来推公式,d[i],表示抛 i 次连续的点数还要抛多少次才能完成.那么状态转移方程就是 d[i] = 1/6*(1+d[i+1]) + 5/6*(1+d[1]), 意思就是说在第 i 次抛和上次相同的概率是1/6,然后加上上次抛的和这一次,再加上和上次不同的,并且又得从第1次开始计算. 边界就是