HDU-4089 Activation (概率DP求概率)
題目大意:一款新游戲注冊賬號時,有n個用戶在排隊。每處理一個用戶的信息時,可能會出現(xiàn)下面四種情況:
1.處理失敗,重新處理,處理信息仍然在隊頭,發(fā)生的概率為p1;
2.處理錯誤,處理信息到隊尾重新排隊,發(fā)生的概率為p2;
3.處理成功,隊頭信息處理成功,出隊,發(fā)生的概率為p3;
4.服務(wù)器故障,隊伍中所有信息丟失,發(fā)生的概率為p4;
小明現(xiàn)在在隊伍中的第m個位置,問當(dāng)他前面的信息條數(shù)不超過k-1時服務(wù)器故障的概率。
題目分析:這道題的狀態(tài)轉(zhuǎn)移方程不難寫。定義狀態(tài)dp(i,j)表示在有 i 個人的隊伍中,他排在第 j 個位置時到達(dá)要求狀態(tài)的概率。則狀態(tài)轉(zhuǎn)移方程為:
dp(i,1)=p1*dp(i,1)+p2*dp(i,i)+p4
dp(i,j)=p1*dp(i,j)+p2*(i,j-1)+p3*dp(i-1,j-1)+p4 (2<=j<=k)
dp(i,j)=p1*dp(i,j)+p2*(i,j-1)+p3*dp(i-1,j-1) (k<j<=i)
整理一下,并另p21=p2/(1-p1),p31=p3/(1-p1),p41=p4/(1-p1),則得到:
dp(i,1)=p21*dp(i,i)+p41
dp(i,j)=p21*dp(i,j-1)+p31*dp(i-1,j-1)+p41 (2<=j<=k)
dp(i,j)=p21*dp(i,j-1)+p31*dp(i-1,j-1) (k<j<=i)
這樣就可以通過遞推求解。
為了書寫方便,把上面的三個轉(zhuǎn)移方程用兩個方程表示出來:
dp(i,1)=p21*dp(i,i)+c(1)
dp(i,j)=p21*dp(i,j-1)+c(j) ?(2<=j<=i)
dp(i,i)可以通過迭代得到:
(1-p21^i)dp(i,i)=∑(p21^(i-j))*c(j) (1<=j<=i)
?
ps:得加特判,否則會WA!!。。。
?
代碼如下:
# include<iostream> # include<cstdio> # include<cmath> # include<cstring> # include<algorithm> using namespace std;const double eps=1e-5;int n,m,k; double p1,p2,p3,p4; double dp[2005][2005];int main() {while(~scanf("%d%d%d",&n,&m,&k)){scanf("%lf%lf%lf%lf",&p1,&p2,&p3,&p4);if(p4<eps){printf("0.00000\n");continue;}double p21=p2/(1-p1);double p31=p3/(1-p1);double p41=p4/(1-p1);dp[1][1]=p41/(1-p21);for(int i=2;i<=n;++i){dp[i][i]=0;for(int j=1;j<=i;++j){if(j==1) dp[i][i]+=pow(p21,i-j)*p41;else if(j>=2&&j<=k) dp[i][i]+=pow(p21,i-j)*(p31*(dp[i-1][j-1])+p41);else dp[i][i]+=pow(p21,i-j)*p31*dp[i-1][j-1];}dp[i][i]/=(1-pow(p21,i));for(int j=1;j<i;++j){if(j==1) dp[i][j]=p21*dp[i][i]+p41;else if(j>=2&&j<=k) dp[i][j]=p21*dp[i][j-1]+p31*dp[i-1][j-1]+p41;else dp[i][j]=p21*dp[i][j-1]+p31*dp[i-1][j-1];}}printf("%.5lf\n",dp[n][m]);}return 0; }
轉(zhuǎn)載于:https://www.cnblogs.com/20143605--pcx/p/5324032.html
總結(jié)
以上是生活随笔為你收集整理的HDU-4089 Activation (概率DP求概率)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Laravel框架开发规范-修订版
- 下一篇: 计算机学院微信公众平台,智慧校园管理,一