hdu 4652(概率dp)

題目鏈接:點擊打開鏈接

題意:給定一個m個面的骰子然後給定兩種詢問,0 m n,表示求丟多少次使得最後丟的n次都相同的期望,1 m n表示求最後丟的n次兩兩不相同的期望。;

題目分析:

我們設dp[i]爲當前爲i個連續的數還需投擲次數的期望搭dp[0]就是解

在相同的情況:

dp[i] 記錄的是已經連續i個相同,到n個不同需要的次數的數學期望
dp[0]= 1+dp[1]
dp[1]= 1+( 1/m*dp[2]+(m-1)/m*dp[1])=1+(dp[2]+(1-m)*dp[1])/m;
dp[2]= 1+(dp[3]+(1-m)*dp[1])/m;
....................
dp[n]= 0

可以推出dp[i] = 1 + ( (m-1)*dp[1] + dp[i+1] ) / m,dp[i+1] = 1 + ( (m-1)*dp[1] + dp[i+2] ) / m;

我們不難看出這是等比數列:dp[0]=(1-m^n)/(1-m);

然而求不同的時候:

dp[0] = 1 + dp[1]
dp[1] = 1 + (dp[1] + (m-1) dp[2]) / m
dp[2] = 1 + (dp[1] + dp[2] + (m-2) dp[3]) / m
dp[i] = 1 + (dp[1] + dp[2] + ... dp[i] + (m-i)*dp[i+1]) / m
dp[i+1]= 1 + (dp[1] + dp[2] + ... dp[i] + dp[i+1] + (m-i-1)*dp[i+1]) / m
...
dp[n] = 0;

解得:dp[i] - dp[i+1] = (m-i-1)/m * (dp[i+1] - dp[i+2]);

因此:dp[0]-dp[1]=1;
dp[1]-dp[2]=1*m/(m-1);
dp[2]-dp[3]=1*m/(m-1)*m/(m-2);
..........

dp[n-1]-dp[n]=1*m/(m-1)*m/(m-2)*.......*m/(m-n+1);


累加起來就是答案
代碼如下:

#include <set>
#include <queue>
#include <math.h>
#include <vector>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <algorithm>
using namespace std;
int main(){
    int t;
    while(scanf("%d",&t)!=EOF){
        int x,n,m;
        while(t--){
            scanf("%d%d%d",&x,&n,&m);
            if(!(x&1)){
                double ans=0;
                for(int i=0;i<m;i++)
                ans+=pow(n+0.0,i);
                printf("%.9f\n",ans);//爲0的時候就是等比數列前n項和
            }
            else{
                double ans=0;
                double tmp=1.0;
                for(int i=1;i<=m;i++){
                    ans+=tmp;
                    tmp=tmp*n/(n-i);
                }//爲1的時候就如我上述所說
                printf("%.9f\n",ans);
            }
        }
    }
    return 0;
}


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