引言
前幾天刷了下微軟的預科生筆試題,感覺略難,今天靜下心仔細思考做出其第一道,特此分享一下。
題目描述
Little Hi is playing a video game. Each time he accomplishes a quest in the game, Little Hi has a chance to get a legendary item.
At the beginning the probability is P%. Each time Little Hi accomplishes a quest without getting a legendary item, the probability will go up Q%. Since the probability is getting higher he will get a legendary item eventually.
After getting a legendary item the probability will be reset to ⌊P/(2I)⌋% (⌊x⌋ represents the largest integer no more than x) where I is the number of legendary items he already has. The probability will also go up Q% each time Little Hi accomplishes a quest until he gets another legendary item.
Now Little Hi wants to know the expected number of quests he has to accomplish to get N legendary items.
Assume P = 50, Q = 75 and N = 2, as the below figure shows the expected number of quests is
2*50%*25% + 3*50%*75%*100% + 3*50%*100%*25% + 4*50%*100%*75%*100% = 3.25
輸入
The first line contains three integers P, Q and N.
1 ≤ N ≤ 106, 0 ≤ P ≤ 100, 1 ≤ Q ≤ 100
輸出
Output the expected number of quests rounded to 2 decimal places.
樣例輸入
50 75 2
樣例輸出
3.25
翻譯一下
小嗨玩電子遊戲。 每當他在遊戲中完成任務時,小嗨都有機會獲得一個傳奇的物品。
一開始概率爲P%。 每次Little Hi完成任務而沒有獲得傳奇物品,概率將上升Q%。 由於概率越來越高,他最終會得到一個傳奇物品。
獲得傳奇物品後,概率將重置爲⌊P/(2I)⌋%(⌊x⌋表示最大整數,不超過x),其中我是其已有的傳奇物品的數量。 每當Little Hi完成任務時,概率也將上升Q%,直到他獲得另一個傳奇物品。
現在,小嗨想知道他要完成的N個傳奇物品的預期數量。
假設P = 50,Q = 75,N = 2,如下圖所示,預期的任務數是
2 * 50%* 25%+ 3 * 50%* 75%* 100%+ 3 * 50%* 100%* 25%+ 4 * 50%* 100%* 75%* 100%= 3.25
解析
分析題可知,此題目實際上是讓求獲得N個物品所需進行任務的數學期望,很容易看出獲得每個物品的概率是獨立事件,故每個物品的期望疊加即爲N個物品所需進行任務的數學期望
代碼如下:(gcc 6.3.1)
#include<stdio.h>
#include<stdbool.h>
double getNextLegend(int p,double q);
double getNextLegend(int p,double q){
double ration_p=1.0*p/100;
double needQuest=1;
double another=1;
while(true){
another*=(1-ration_p);
needQuest+=another;
ration_p+=q;
if(ration_p>=1.0)
break;
}
return needQuest;
}
int main(void){
int P,Q,N;
int i;
scanf("%d %d %d",&P,&Q,&N);
double result=0.0;
double ration_Q=1.0*Q/100;
for(i=0;i<N;i++){
double getLegend=getNextLegend(P,ration_Q);
result+=getLegend;
P/=2;
}
printf("%.2f",result);
return 0;
}
結束語
看到題目描述,其實很容易想到利用深度優先遍歷遍歷解空間樹來做,但是這樣做會造成空間複雜度過高,而且要用遞歸遍歷整個子樹,我開始就是按照這個思路去做,但感覺很麻煩,最後看到別人提供的思路即求每個物品的期望疊加,簡潔清晰,但這就需要在思考時不侷限於題目,深刻分析題目從而最終找到解決方案。