zoukankan      html  css  js  c++  java
  • poj 2151 Check the difficulty of problems (检查问题的难度)

    poj 2151 Check the difficulty of problems

    http://poj.org/problem?id=2151

    题意:此刻有tn道题目,有dn个队伍,知道每个队伍能答对每个题目的概率,问:冠军至少答对n(1<=n<=tn)道题目,其他队伍至少要答对一道题目的概率

    dp+概率

    方法:

    f[i][j]第i队做对第j个题的概率

    g[i][j][k]第i队前j个题做对k个题的概率

    dp状态转移方程:g[i][j][k] = g[i][j-1][k-1]*f[i][j] + g[i][j-1][k]*(1-f[i][j])

    这样

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

    由于冠军队可以不止一队,即允许存在并列冠军

    则原来的所求的概率可以转化为:

    每队均至少做一题的概率P1 减去 每队做题数均在1到N-1之间的概率P2(**)

     1 /*
     2 Problem: 2151        User: bibier
     3 Memory: 5120K        Time: 47MS
     4 Language: G++        Result: Accepted
     5 */
     6 
     7 #include <stdio.h>
     8 #include <string.h>
     9 #include <iostream>
    10 #include <algorithm>
    11 #include <cstdio>
    12 #include <cstring>
    13 #include <cmath>
    14 #include <stack>
    15 #include <queue>
    16 #include <vector>
    17 using namespace std;
    18 #define M 0x0f0f0f0f
    19 #define min(a,b) (a>b?b:a)
    20 #define max(a,b) (a>b?a:b)
    21 
    22 
    23 float f[1003][33];//f[i][j]第i队做对第j个题的概率
    24 float g[1003][33][33];//g[i][j][k]第i队前j个题做对k个题的概率
    25 
    26 //g[i][j][k] = g[i][j-1][k-1]*f[i][j] + g[i][j-1][k]*(1-f[i][j])
    27 int main()
    28 {
    29     int tn,dn,n;
    30     int i,j,k;
    31     while(scanf("%d %d %d",&tn,&dn,&n)!=EOF)
    32     {
    33         if(tn==0&&dn==0&&n==0)
    34             break;
    35         memset(g,0,sizeof(g));
    36         memset(f,0,sizeof(f));
    37 
    38         for(i=1; i<=dn; i++)
    39             for(j=1; j<=tn; j++)
    40                 scanf("%f",&f[i][j]);
    41 
    42         for(i=1; i<=dn; i++)
    43         {
    44             g[i][1][0]=1-f[i][1];
    45             g[i][1][1]=f[i][1];
    46         }
    47 
    48         for(i=1; i<=dn; i++)
    49             for(j=2; j<=tn; j++)
    50                 for(k=0; k<=j; k++)
    51                 {
    52                     if(k==j)
    53                         g[i][j][k] = g[i][j-1][k-1]*f[i][j];
    54                     else if(k==0)
    55                         g[i][j][k] = g[i][j-1][k]*(1-f[i][j]);
    56                     else
    57                         g[i][j][k] = g[i][j-1][k-1]*f[i][j] + g[i][j-1][k]*(1-f[i][j]);
    58                 }
    59         float all=1;
    60         for(i=1; i<=dn; i++) //每队至少做对一道题的最终概率
    61             all*=(1-g[i][tn][0]);
    62 
    63         float midall=1;
    64         for(i=1; i<=dn; i++)
    65         {
    66             float everyd=0;
    67             for(j=1; j<n; j++)
    68             {
    69                 everyd+=g[i][tn][j];
    70             }
    71             midall*=everyd;
    72         }
    73         all-=midall;
    74         printf("%.3f\n",all);
    75     }
    76     return 0;
    77 }
    View Code

    状态转移方程:动态规划中本阶段的状态往往是上一阶段状态上一阶段决策的结果。如果给定了第K阶段的状态Sk以及决策uk(Sk),则第K+1阶段的状态Sk+1也就完全确定。也就是说Sk+1与Sk,uk之间存在一种明确的数量对应关系,记为Tk(Sk,uk),即有Sk+1= Tk(Sk,uk)。 这种用函数表示前后阶段关系的方程,称为状态转移方程。在上例中状态转移方程为 Sk+1= uk(Sk) 。

  • 相关阅读:
    LeetCode 345. Reverse Vowels of a String 题解
    LeetCode 344. Reverse String 题解
    LeetCode 27. Remove Element 题解
    LeetCode 61. Rotate List 题解
    LeetCode 19.Remove Nth Node From End of List 题解
    Android耗电量
    Android 使用adb查看和修改电池信息
    Android AOP AspectJ 插桩
    Flask相关用法
    Monkey日志信息的11种Event percentage
  • 原文地址:https://www.cnblogs.com/bibier/p/3896799.html
Copyright © 2011-2022 走看看