【HDOJ】4089 Activation

1. 题目描述
长度为n的等待队列,tomato处于第m个,有如下四种可能:
(1)激活失败,概率为$p_1$,队列中的顺序不变;
(2)连接失败,概率为$p_2$,队头玩家重新排在队尾;
(3)激活成功,概率为$p_3$,队头出队;
(4)服务器down机,概率为$p_4$,队伍停止。
问当服务器当机时,tomato处在队列前k个人的概率是多少?

2. 基本思路
这显然是个概率DP。dp[i][j]表示队伍中有i个人,tomato处在第j个满足所求的概率。
\begin{align}
    j=1,        (1-p_1) \times dp[i][j] &= p_2 \times dp[i][i] + p_4                                \\
    j\in [2,k], (1-p_1) \times dp[i][j] &= p_2 \times dp[i][j-1] + p_3 \times dp[i-1][j-1] + p_4    \\
    j>k,        (1-p_1) \times dp[i][j] &= p_2 \times dp[i][j-1] + p_3 \times dp[i-1][j-1]
\end{align}
显然,对于$\forall i$均存在i个等式,组成方程组。可以通过(1)式代入,解出dp[i][i]。
注意$p_4 \rightarrow 0$时,即不会发生down机的情况。概率为0。

3. 代码

  1 /* 4089 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <bitset>
 12 #include <algorithm>
 13 #include <cstdio>
 14 #include <cmath>
 15 #include <ctime>
 16 #include <cstring>
 17 #include <climits>
 18 #include <cctype>
 19 #include <cassert>
 20 #include <functional>
 21 #include <iterator>
 22 #include <iomanip>
 23 using namespace std;
 24 //#pragma comment(linker,"/STACK:102400000,1024000")
 25 
 26 #define sti                set<int>
 27 #define stpii            set<pair<int, int> >
 28 #define mpii            map<int,int>
 29 #define vi                vector<int>
 30 #define pii                pair<int,int>
 31 #define vpii            vector<pair<int,int> >
 32 #define rep(i, a, n)     for (int i=a;i<n;++i)
 33 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 34 #define clr                clear
 35 #define pb                 push_back
 36 #define mp                 make_pair
 37 #define fir                first
 38 #define sec                second
 39 #define all(x)             (x).begin(),(x).end()
 40 #define SZ(x)             ((int)(x).size())
 41 #define lson            l, mid, rt<<1
 42 #define rson            mid+1, r, rt<<1|1
 43 
 44 const double eps = 1e-8;
 45 const int maxn = 2005;
 46 double dp[maxn][maxn];
 47 double P[maxn];
 48 int n, kth, k;
 49 double p1, p2, p3, p4;
 50 
 51 void solve() {
 52     if (p4 < eps) {
 53         puts("0.00000");
 54         return ;
 55     }
 56 
 57     dp[1][1] = p4 / (1-p1-p2);
 58     double p21 = p2 / (1-p1);
 59     double p31 = p3 / (1-p1);
 60     double p41 = p4 / (1-p1);
 61     rep(i, 2, n+1) {
 62         double coef = 0.0, cons = 0.0;
 63 
 64         rep(j, 1, i+1) {
 65             if (j == 1) {
 66                 coef = p21;
 67                 cons = p41;
 68             } else if (j <= k) {
 69                 cons = p41 + p31 * dp[i-1][j-1] + p21 * cons;
 70                 coef = p21 * coef;
 71             } else {
 72                 cons = p31 * dp[i-1][j-1] + p21 * cons;
 73                 coef = p21 * coef;
 74             }
 75         }
 76 
 77         dp[i][i] = cons / (1.0 - coef);
 78         rep(j, 1, i) {
 79             if (j == 1) {
 80                 dp[i][j] = p21 * dp[i][i] + p41;
 81             } else if (j <= k) {
 82                 dp[i][j] = p21 * dp[i][j-1] + p31 * dp[i-1][j-1] + p41;
 83             } else {
 84                 dp[i][j] = p21 * dp[i][j-1] + p31 * dp[i-1][j-1];
 85             }
 86         }
 87     }
 88 
 89     double ans = dp[n][kth];
 90     printf("%.05lf\n", ans);
 91 }
 92 
 93 int main() {
 94     ios::sync_with_stdio(false);
 95     #ifndef ONLINE_JUDGE
 96         freopen("data.in", "r", stdin);
 97         freopen("data.out", "w", stdout);
 98     #endif
 99 
100     while (cin >> n >> kth >> k >> p1 >> p2 >> p3 >> p4) {
101         solve();
102     }
103 
104     #ifndef ONLINE_JUDGE
105         printf("time = %d.\n", (int)clock());
106     #endif
107 
108     return 0;
109 }

 

你可能感兴趣的:(【HDOJ】4089 Activation)