zoukankan      html  css  js  c++  java
  • poj2151_概率dp

    题目链接:http://poj.org/problem?id=2151

    题意:

    ACM比赛中,共M道题,T个队,pij表示第i队解出第j题的概率 

    问 每队至少解出一题且冠军队至少解出N道题的概率

    分析:
    对于需要求得概率比较容易想到:
    假设p1为每个队至少解出一题的概率,这个容易算出。
    假设p2为每个队至少解出一题但是不超过n-1题的概率
    所以最终答案为:p1-p2
    现在问题是如何求出p2?
    假设dp[i][j]表示第i个队解出的题目<=j的概率
    则dp[i][j]=解出1题+解出2题+...解出j题的概率
    现在问题转化为如何求解出1,2,3...k题的概率
    假设x[i][j][k]表示第i个队在前j题解出k题的概率
    则:
    x[i][j][k]=x[i][j-1][k-1]*p[i][j]+x[i][j-1][k]*(1-p[i][j]);
    所以x[i][M][k]表示的就是第i个队解出k题的概率

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <cstdlib>
     6 #include <cmath>
     7 #include <set>
     8 #include <map>
     9 #include <queue>
    10 #include <vector>
    11 #define INF 0x3f3f3f3f
    12 using namespace std;
    13 
    14 double an[1010][35], dp[1010][35], sn[1010][35][35];
    15 int main()
    16 {
    17     int n, t, m;
    18     while(~scanf("%d %d %d", &m, &t, &n) && n + t + m)
    19     {
    20         memset(sn, 0, sizeof(sn));
    21         memset(dp, 0, sizeof(dp));
    22         double res2 = 1;
    23         for(int i = 1; i <= t; i++)
    24         {
    25             double temp = 1;
    26             for(int j = 1; j <= m; j++)
    27             {
    28                 scanf("%lf", &an[i][j]);
    29                 temp *= (1 - an[i][j]);
    30             }
    31             res2 *= (1 - temp);
    32         }
    33         for(int i = 1; i <= t; i++)
    34         {
    35             sn[i][0][0] = 1;
    36         }
    37         for(int i = 1; i <= t; i++)
    38         {
    39             for(int j = 1; j <= m; j++)
    40             {
    41                 for(int k = 0; k <= n; k++)
    42                 {
    43                     if(k == 0)
    44                         sn[i][j][k] = (1 - an[i][j]) * sn[i][j - 1][k];
    45                     else
    46                     {
    47                         sn[i][j][k] = sn[i][j - 1][k - 1] * an[i][j] + sn[i][j - 1][k] * (1 - an[i][j]);
    48                     }
    49                 }
    50             }
    51         }
    52         for(int i = 1; i <= t; i++)
    53         {
    54             for(int j = 1; j < n; j++){
    55                 dp[i][n] += sn[i][m][j];
    56             }
    57         }
    58         double res = 1;
    59         for(int i = 1; i <= t; i++)
    60             res *= dp[i][n];
    61         printf("%.3lf
    ", res2 - res);
    62     }
    63     return 0;
    64 }
  • 相关阅读:
    axios封装
    python 分析列表中的字典
    python 列表解析学习
    Java常用ORM框架
    Kafka 会不会丢消息?怎么处理的?
    Node.js学习笔记【八】
    Node.js学习笔记【七】
    Node.js学习笔记【六】
    Node.js学习笔记【五】
    Node.js学习笔记【四】
  • 原文地址:https://www.cnblogs.com/luomi/p/5699210.html
Copyright © 2011-2022 走看看