1 /* 2 題目大意:註冊一款遊戲須要排隊,一共有四種事件: 3 1.註冊失敗,隊列不變,機率爲p1 4 2.註冊過程當中斷開鏈接,正在註冊的人排到隊列的末尾,機率爲p2 5 3.註冊成功,移出隊列,機率爲p3 6 4.服務器暫停服務,機率爲p4 7 求一我的他前面有不超過k-1我的的時候暫停服務的機率。 8 從前日後推,統計答案太麻煩,因此選擇從後往前推。 9 dp(i,j)表示一共i我的,他排在j位置的達到目標狀態的機率。 10 j==1 dp[i][j]=dp[i][j]*p1+dp[i][i]*p2+p4; 11 1<j<=k dp[i][j]=dp[i][j]*p1+dp[i][j-1]*p2+dp[i-1][j-1]*p3+p4; 12 j> k dp[i][j]=dp[i][j]*p1+dp[i][j-1]*p2+dp[i-1][j-1]*p3; 13 {i>=j} 14 化簡: 15 j==1 dp[i][j]=dp[i][i]*p21+p41; 16 1<j<=k dp[i][j]=dp[i][j-1]*p21+dp[i-1][j-1]*p31+p41; 17 j> k dp[i][j]=dp[i][j-1]*p21+dp[i-1][j-1]*p31; 18 p=1-p1; 19 p21=p2/p; 20 p31=p3/p; 21 p41=p4/p; 22 dp[1][1]=dp[1][1]*p21+p41,得dp[1][1]=p41/(1-p21); 23 24 j=1 dp[i][1]=dp[i][i]*p21+p41; 25 j=2 dp[i][2]=dp[i][1]*p21+dp[i-1][1]*p31+p41; 26 ................................................................................. 27 j==k dp[i][k]=dp[i][k-1]*p21+dp[i-1][k-1]*p31; 28 j==k+1 dp[i][j]=dp[i][k]*p21+dp[i-1][k]*p31; 29 ................................................................................. 30 j==i dp[i][i]=dp[i][i-1]*p21+dp[i-1][i-1]*p31; 31 可發現後面一部分都是常數項(遞推過來已求出的),設後面一部分爲c[j] 32 能夠消元求解 33 ai=(((.....(((ai*p+c1)*p+c2)*p+c5)*p+c6*)............+ci) 34 ai=ai*p^i+c1*p^(i-1)+c2*p^(i-2)+.......+ci*p^0 35 可求出ai。 36 */ 37 #include <iostream> 38 #include <cstdio> 39 #include <cstring> 40 #include <cmath> 41 using namespace std; 42 43 const double eps=1e-8; 44 const int maxn=2005; 45 double dp[maxn][maxn]; 46 double c[maxn]; 47 double pp[maxn]={1.0}; 48 49 int main() 50 { 51 int n,m,k,i,j; 52 double p0,p1,p2,p3,p4,p5,p6,p7; 53 while(~scanf("%d%d%d",&n,&m,&k)) 54 { 55 scanf("%lf%lf%lf%lf",&p1,&p2,&p3,&p4); 56 if(fabs(p4)<eps){puts("0.00000");continue;} 57 p0=1-p1;p5=p2/p0;p6=p3/p0;p7=p4/p0; 58 for(i=1;i<=n;i++) pp[i]=pp[i-1]*p5; 59 dp[1][1]=p7/(1-p5); 60 c[1]=p7; 61 for(i=2;i<=n;i++) 62 { 63 for(j=2;j<=i;j++) 64 { 65 c[j]=dp[i-1][j-1]*p6; 66 if(j<=k) c[j]+=p7; 67 } 68 double temp=0.0; 69 for(j=1;j<=i;j++) temp+=c[j]*pp[i-j]; 70 dp[i][i]=temp/(1-pp[i]); 71 dp[i][1]=p5*dp[i][i]+c[1]; 72 for(j=2;j<i;j++) 73 dp[i][j]=p5*dp[i][j-1]+c[j]; 74 } 75 printf("%.5lf\n",dp[n][m]); 76 } 77 return 0; 78 }