從零開始的算法題生活(二)

引言

前幾天刷了下微軟的預科生筆試題,感覺略難,今天靜下心仔細思考做出其第一道,特此分享一下。

題目描述

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;
}

結束語

看到題目描述,其實很容易想到利用深度優先遍歷遍歷解空間樹來做,但是這樣做會造成空間複雜度過高,而且要用遞歸遍歷整個子樹,我開始就是按照這個思路去做,但感覺很麻煩,最後看到別人提供的思路即求每個物品的期望疊加,簡潔清晰,但這就需要在思考時不侷限於題目,深刻分析題目從而最終找到解決方案。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章