1. 程式人生 > >m面骰子投擲n次,求最大的點的期望值

m面骰子投擲n次,求最大的點的期望值

/*骰子一共有m個面,第一面有一個點,第二面有兩個點,以此類推,第m個面有m個點。
Twilight Sparkle很清楚的知道,每當她丟一次骰子,都有可能隨機出現其中的一個面。
並且她還知道,每次扔出的概率都是獨立的。現在請你幫助她計算下,當她扔出n次骰子後,所得的最大的點的預期值是多少?


輸入值:包含2個整數,m和n (1 ≤ m, n ≤ 105)。


輸出值:輸出的結果對應於最大的點的預期值,結果誤差在10-4範圍內都視為正確答案。


示例,比如在假定m=2,n=2的情況下(即骰子只有兩面,扔2次的情況):


你第一次扔了1個1,第二次扔了1個2,最大結果為2。
你第一次扔了1個1,第二次扔了1個1,最大結果為1。
你第一次扔了1個2,第二次扔了1個1,最大結果為2。
你第一次扔了1個2,第二次扔了1個2,最大結果為2。
由於出現上述四種情況的概率都為0.25,那麼預期值為


(2 + 1 + 2 + 2)* 0.25 = 7/4
*/


#include<iostream>

using namespace std;

class Dice{
int m;//骰子的面數
int n;//投擲的次數
public:
Dice(){
cout << "請輸入骰子的面數:";
cin >> this->m;
cout << "請輸入投擲的次數:";
cin >> this->n;
}
int getm(){ return this->m; }//獲得投擲的面數
int getn(){ return this->n; }//獲得投擲的次數

};//並沒有必要寫類,腦洞有點大

double Expect(int m, int n, int max = 1){//求期望值
double E = 1;//最後一次擲得得值為m
if (n != 1){//不止擲一次
for (int i = 1; i < max; i++){
E += (1.0 / m)*Expect(m, n - 1, max);//最後一次擲得的骰子數為1--max
}
for (int j = max; j < m; j++){
E += (1.0 / m)*Expect(m, n - 1, j);//最後一次擲得的骰子數為max--m-1
}
}
else{//擲一次,這也是給遞迴賦了一個初值
for (int i = 1; i < max; i++){
E += (1.0 / m)*max;
}
for (int j = max; j < m; j++){
E += (1.0 / m)*j;
}
}
return E;
}
int main(){
Dice d;
cout<<Expect(d.getm(), d.getn(), 1);
cout << endl;
return 0;
}