zoukankan      html  css  js  c++  java
  • 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
    ",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

  • 相关阅读:
    格式化数字,将字符串格式的数字,如:1000000 改为 1 000 000 这种展示方式
    jquery图片裁剪插件
    前端开发采坑之安卓和ios的兼容问题
    页面消息提示,上下滚动
    可以使用css的方式让input不能输入文字吗?
    智慧农村“三网合一”云平台测绘 大数据 农业 信息平台 应急
    三维虚拟城市平台测绘 大数据 规划 三维 信息平台 智慧城市
    农业大数据“一张图”平台测绘 大数据 房产 国土 农业 信息平台
    应急管理管理局安全生产预警平台应急管理系统不动产登记 测绘 大数据 规划 科教 三维 信息平台
    地下综合管廊管理平台测绘 大数据 地下管线 三维 信息平台
  • 原文地址:https://www.cnblogs.com/Leohh/p/7583627.html
Copyright © 2011-2022 走看看