zoukankan      html  css  js  c++  java
  • hdu 4050 概率dp

    //dp[i][state]

    //状态转移方程的选取:题目的意思是,从点 i 优先考虑到达 i + A 点的情况,若不能到达 i + A 点,则考虑到达 i + A + 1 点的情况...以此类推,直到考虑完到达 i + B 点的情况。对于最坏的情况,每一个点都有 B - A + 1 个后继点,所以由前向后推比较合适。

    //题目是要求当走到 [1...n] 中的某一点不能继续走的时候 或者 走到超出 n 点的位置时的总步数期望,因为在 [1...n] 中的任意一点都可能不能继续走,超出 n 点的位置也有可能有很多(namely 状态终点非常多,而且一般计算期望的方式是状态终点置零,从后往前推),所以我们换个方式思考这个问题。注意到 到达 [i, state] 的概率 * 1,其实就是从[i, state] 的前驱状态到达 [i, state] 的步数期望,将这些 1 步的期望全部加起来,就是题目要求的总步数期望

     1 #include "iostream"
     2 #include "cstdio"
     3 #include "cstring"
     4 #include "algorithm"
     5 #include "cmath"
     6 using namespace std;
     7 const double eps = 1e-10;
     8 double dp[4010][4], p[4010][4];
     9 int n, A, B;
    10 
    11 int main()
    12 {
    13     int T, i, j;
    14     scanf("%d", &T);
    15     while(T--) {
    16         scanf("%d%d%d", &n, &A, &B);
    17         for(i = 1; i <= n; ++i)
    18             for(j = 0; j <= 3; ++j)
    19                 scanf("%lf", &p[i][j]);
    20         for(i = n + 1; i <= n + A; ++i)
    21             for(j = 0; j <= 3; ++j)
    22                 p[i][j] =  (j == 3);
    23         memset(dp, 0, sizeof(dp));
    24         dp[0][3] = 1;
    25         for(i = 0; i <= n; ++i) {
    26             double p1, p2, p3;
    27             p1 = p2 = p3 = 1;
    28             for(j = i + A; j <= i + B; ++j) {
    29                 if(j > n + A)
    30                     break;
    31                 dp[j][2] += dp[i][1] * p1 * p[j][2];
    32                 dp[j][3] += dp[i][1] * p1 * p[j][3];
    33                 p1 *= (p[j][0] + p[j][1]);
    34                 dp[j][1] += dp[i][2] * p2 * p[j][1];
    35                 dp[j][3] += dp[i][2] * p2 * p[j][3];
    36                 p2 *= (p[j][0] + p[j][2]);
    37                 dp[j][1] += dp[i][3] * p3 * p[j][1];
    38                 dp[j][2] += dp[i][3] * p3 * p[j][2];
    39                 dp[j][3] += dp[i][3] * p3 * p[j][3];
    40                 p3 *= p[j][0];
    41             }
    42         }
    43         double res = 0;
    44         for(i = 1; i <= n + A; ++i)
    45             for(j = 1; j <= 3; ++j)
    46                 res += dp[i][j];
    47         printf("%.8f
    ", res);
    48     }
    49 }

    //附上一种等价的写法

     1 #include "iostream"
     2 #include "cstdio"
     3 #include "cstring"
     4 #include "algorithm"
     5 #include "cmath"
     6 using namespace std;
     7 const double eps = 1e-10;
     8 double dp[4010][4], p[4010][4];
     9 int n, A, B;
    10 
    11 int main()
    12 {
    13     int T, i, j;
    14     scanf("%d", &T);
    15     while(T--) {
    16         scanf("%d%d%d", &n, &A, &B);
    17         for(i = 1; i <= n; ++i)
    18             for(j = 0; j <= 3; ++j)
    19                 scanf("%lf", &p[i][j]);
    20         for(i = n + 1; i <= n + A; ++i)
    21             for(j = 0; j <= 3; ++j)
    22                 p[i][j] =  (j == 3);
    23         memset(dp, 0, sizeof(dp));
    24         dp[0][3] = 1;
    25         double res = 0;
    26         for(i = 0; i <= n; ++i) {
    27             double p1, p2, p3;
    28             p1 = p2 = p3 = 1;
    29             for(j = i + A; j <= i + B; ++j) {
    30                 if(j > n + A)
    31                     break;
    32                 res += dp[i][1] * p1 * p[j][2] + dp[i][1] * p1 * p[j][3] + dp[i][2] * p2 * p[j][1] + dp[i][2] * p2 * p[j][3] + dp[i][3] * p3 * p[j][1] + dp[i][3] * p3 * p[j][2] + dp[i][3] * p3 * p[j][3];
    33                 dp[j][2] += dp[i][1] * p1 * p[j][2];
    34                 dp[j][3] += dp[i][1] * p1 * p[j][3];
    35                 p1 *= (p[j][0] + p[j][1]);
    36                 dp[j][1] += dp[i][2] * p2 * p[j][1];
    37                 dp[j][3] += dp[i][2] * p2 * p[j][3];
    38                 p2 *= (p[j][0] + p[j][2]);
    39                 dp[j][1] += dp[i][3] * p3 * p[j][1];
    40                 dp[j][2] += dp[i][3] * p3 * p[j][2];
    41                 dp[j][3] += dp[i][3] * p3 * p[j][3];
    42                 p3 *= p[j][0];
    43             }
    44         }
    45         printf("%.8f
    ", res);
    46     }
    47 }
  • 相关阅读:
    算法提高 12-1三角形
    poj3723_Conscription
    算法提高 8-1因式分解
    算法提高 道路和航路
    算法训练 安慰奶牛
    最短路问题(Bellman/Dijkstra/Floyd)
    最小生成树 prime+heap
    算法训练 最短路
    算法训练 最大的算式
    poj3255 Roadblocks
  • 原文地址:https://www.cnblogs.com/AC-Phoenix/p/4295344.html
Copyright © 2011-2022 走看看