Loading

题解 HDU4652 Dice

题意

多次投一个m面体骰子,求 1)最后n次相同的期望次数 2)最后n次都不相同的期望次数

\(n\leq m\),且运算过程保证不超过int

思路

我真的不会期望

基本上就是yyb的推导思路

首先我们定义状态\(f_i\)表示已经有i次相同/不相同,到达目标状态的期望次数

记住到达目标状态,这样才能理解期望的推导

对于问题1可得

\[f_i=\frac 1 m f_{i+1} + \frac{m-1}{m}f_1+1 \]

然后整理出

\[m(f_i-f_{i-1})=f_{i+1}-f_i \]

作差,然后带回\(f_0-f_1=1\)

得到$$f_0=1+m+m2+m3+...+m^{n-1}= \frac{m^n-1}{1-m} $$

对于问题2可得

\[f_i=\frac{m-i}{m}f_{i+1}+\frac{\sum^{i}_{j=1}f_j}{m}+1 \]

同状态1作差带回相加可得

\[f_0=\sum^{n-1}_{i=0}\prod^{i}_{j=0}\frac{m}{m-j} \]

代码

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<climits>
#include<string>
#include<deque>
#include<bitset>
#include<cstring>
#include<stack>
#include<cstdlib>
#include<iostream>
#include<ctime>
#include<algorithm>
using namespace std;
int T;
int n,m,opt;
double solve0(int m,int n){return (pow(m,n)-1.0)/((m-1)*1.0);}
double solve1(int m,int n){
	double ans=1,d=1;
	for(int i=1;i<n;i++){
		d=1.0*m/(m-i)*d;ans+=d;
	}
	return ans;
}
int main(){
	while(scanf("%d",&T)!=EOF){
		for(int i=1;i<=T;i++){
			scanf("%d%d%d",&opt,&m,&n);
			printf("%.8lf\n",opt==0?solve0(m,n):solve1(m,n));
		}
	}
	return 0;
}
posted @ 2020-11-18 08:52  fpjo  阅读(71)  评论(0编辑  收藏  举报