hdu 4625 Dice(概率DP)

 

Dice

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 180    Accepted Submission(s): 121 Special Judge

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: ask for the expected number of tosses until the last n times results are
all same. 1 m n: ask for the expected number of tosses until the last n consecutive results are pairwise different.
 

 

Input
The first line contains a number T.(1≤T≤100) The next T line each line contains a query as we mentioned above. (1≤m,n≤10 6) For second kind query,
we guarantee n≤m. And in order to avoid potential precision issue, we guarantee the result for our query will not exceeding 10 9  in this problem.
 

 

Output
For each query, output the corresponding result. The answer will be considered correct if the absolute or relative error doesn't exceed 10 -6.
 

 

Sample Input
6
0 6 1
0 6 3
0 6 5
1 6 2
1 6 4
1 6 6
10
1 4534 25
1 1232 24
1 3213 15
1 4343 24
1 4343 9
1 65467 123
1 43434 100
1 34344 9
1 10001 15
1 1000000 2000
 
 

 

Sample Output
1.000000000
43.000000000
1555.000000000
2.200000000
7.600000000
83.200000000
25.586315824
26.015990037
15.176341160
24.541045769
9.027721917
127.908330426
103.975455253
9.003495515
15.056204472
4731.706620396
 

 

Source

 

题意:

输入 :op,m,n;

op=0:表示最后n次骰子的面都是一样的!!

op=1:表示最后n次骰子的面是互不相同的!!

 

对于op=0:对于i状态(即最后i次骰子的面都是一样的,比如是xx。。xx),然后接下来我可以有1/m的概率掷到x,即有1/m的概率可以转移到i+1这个状态

  同时,若我可以有1-1/m的概率掷到非x,比如序列变为(xx。。xxy),即有1-1/m的概率可以转移到i=1这个状态;

  所以状态转移为:dp[i]=1/m*dp[i+1]+(1-1/m)*dp[1]+1;  (__dp[n]=0__);

  然后就是n-1个方程递推下去求出dp[1]即可;

 

对于op=1:对于i状态(即最后i次骰子的面都是互不相同的,比如是xy。。ab),然后接下来我可以有1-i/m的概率掷到新的元素,比如序列变为(xy。。abc),

  即有1-i/m的概率可以转移到i+1这个状态

  同时,我各有可以有1/m的概率分别转移到(i,i-1,i-2,。。,1)这些状态,比如序列变为(xy。。abx,即转为i状态!!!),

  所以状态转移为:dp[i]=(1-i/m)*dp[i+1]+1/m*(dp[i]+dp[i-1]+..+dp[1])+1;  (__dp[n]=0__);

  然后就是n-1个方程递推下求解啦(这别要细心奥!!);

 

 1 #include<stdio.h>
 2 
 3 int m,n;
 4 void DP1()
 5 {
 6     int i;
 7     double ans,a,b;
 8      a=1.0*(m-1)/m;
 9      b=1.0;
10     for(i=1;i<=n-2;i++)
11     {
12         a=a*1.0/m+1.0*(m-1)/m;
13         b=b/m+1;
14     }
15     if(n==1)ans=1.0;
16     else ans=b/(1-a)+1;//b/(1-a)为dp[1]; 
17     printf("%.9f\n",ans);    
18 }
19 
20 void DP2()
21 {
22     int i;
23     double ans=1.0,tmp=1.0;
24     for(i=1;i<=n-1;i++)//找到递推关系求解!! 
25     {
26         tmp=tmp*m/(m-i);
27         ans+=tmp;    
28     }
29     printf("%.9f\n",ans);
30 }
31 
32 
33 int main()
34 {
35     int T,i,op;
36     
37     while(~scanf("%d",&T))
38     {
39         while(T--)
40         {
41             scanf("%d%d%d",&op,&m,&n);
42             if(op==0)
43                 DP1();
44             else
45                 DP2();        
46         }
47         
48     }
49 }
View Code

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/skykill/p/3245580.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值