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
题意:
输入 :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个方程递推下求解啦(这别要细心奥!!);
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
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 }