zoukankan      html  css  js  c++  java
  • POJ 2151 Check the difficulty of problems 概率dp+01背包

    题目链接:

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

    Check the difficulty of problems

    Time Limit: 2000MS
    Memory Limit: 65536K
    #### 问题描述 > Organizing a programming contest is not an easy job. To avoid making the problems too difficult, the organizer usually expect the contest result satisfy the following two terms: > 1. All of the teams solve at least one problem. > 2. The champion (One of those teams that solve the most problems) solves at least a certain number of problems. > > Now the organizer has studied out the contest problems, and through the result of preliminary contest, the organizer can estimate the probability that a certain team can successfully solve a certain problem. > > Given the number of contest problems M, the number of teams T, and the number of problems N that the organizer expect the champion solve at least. We also assume that team i solves problem j with the probability Pij (1 <= i <= T, 1<= j <= M). Well, can you calculate the probability that all of the teams solve at least one problem, and at the same time the champion team solves at least N problems? > #### 输入 > The input consists of several test cases. The first line of each test case contains three integers M (0 < M <= 30), T (1 < T <= 1000) and N (0 < N <= M). Each of the following T lines contains M floating-point numbers in the range of [0,1]. In these T lines, the j-th number in the i-th line is just Pij. A test case of M = T = N = 0 indicates the end of input, and should not be processed.

    输出

    For each test case, please output the answer in a separate line. The result should be rounded to three digits after the decimal point.

    样例输入

    2 2 2
    0.9 0.9
    1 0.9
    0 0 0

    样例输出

    0.972

    题意

    acm竞赛总共有m道题,t个队伍,并且知道第i个队伍做出第j道题的概率,求保证每个队伍都至少做出一道题,并且冠军队伍至少做出n道题的概率。

    题解

    原问题可以转换为求:所有的队伍都至少做出一题的概率-每个队伍都做出(1~n-1)道题的总概率。

    代码

    #include<map>
    #include<set>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<functional>
    using namespace std;
    #define X first
    #define Y second
    #define mkp make_pair
    #define lson (o<<1)
    #define rson ((o<<1)|1)
    #define mid (l+(r-l)/2)
    #define sz() size()
    #define pb(v) push_back(v)
    #define all(o) (o).begin(),(o).end()
    #define clr(a,v) memset(a,v,sizeof(a))
    #define bug(a) cout<<#a<<" = "<<a<<endl
    #define rep(i,a,b) for(int i=a;i<(b);i++)
    #define scf scanf
    #define prf printf
    
    typedef __int64 LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<pair<int,int> > VPII;
    
    const int INF=0x3f3f3f3f;
    const LL INFL=0x3f3f3f3f3f3f3f3fLL;
    const double eps=1e-9;
    
    const double PI = acos(-1.0);
    
    //start----------------------------------------------------------------------
    
    const int maxn=3333;
    const int maxm=33;
    ///n个队伍,m道题,冠军至少做mm道。
    int n,m,mm;
    
    double dp[maxn][maxm];
    double dp2[maxm][maxm];
    double mat[maxn][maxm];
    
    void init(){
        clr(dp,0);
    }
    
    int main() {
        while(scf("%d%d%d",&m,&n,&mm)==3&&n){
            init();
            for(int i=1;i<=n;i++){
                clr(dp2,0);
                ///01背包,dp2[j][k],求第i个队伍前j道题做出k道的概率。
                dp2[0][0]=1.0;
                for(int j=1;j<=m;j++){
                    double x; scf("%lf",&x);
                    for(int k=0;k<=j;k++){
                        dp2[j][k]+=dp2[j-1][k]*(1-x);
                        if(k) dp2[j][k]+=dp2[j-1][k-1]*x;
                    }
                }
                ///mat[i][k]:第i个队伍m道题做出k道的概率。
                for(int k=0;k<=mm-1;k++) mat[i][k]=dp2[m][k];
            }
    
            ///biger:所有的队伍都至少做出一题的概率
            double biger=1.0;
            for(int i=1;i<=n;i++) biger*=(1-mat[i][0]);
    
            ///dp[i][j]:统计前i个队伍中第i个队伍做了j题的总概率。
            clr(dp,0);
            for(int j=1;j<=mm-1;j++) dp[1][j]=mat[1][j];
            for(int i=2;i<=n;i++){
                for(int j=1;j<=mm-1;j++){
                    for(int k=1;k<=mm-1;k++){
                        dp[i][j]+=dp[i-1][k]*mat[i][j];
                    }
                }
            }
    
            ///sum:每个队伍都做出(1~mm-1)道题的总概率
            double sum=0;
            for(int i=1;i<=mm-1;i++) sum+=dp[n][i];
    
            prf("%.3f
    ",biger-sum);
        }
        return 0;
    }
    
    //end-----------------------------------------------------------------------
  • 相关阅读:
    react ts axios 配置跨域
    npm run eject“Remove untracked files, stash or commit any changes, and try again.”错误
    java 进程的参数和list的线程安全
    帆软报表 大屏列表跑马灯效果JS
    帆软报表 快速复用数据集,避免重复劳动
    分析云 OA中部门分级思路和实现方法
    分析云 分段器 只显示一个块的数据
    分析云 更改服务默认的端口号
    分析云U8项目配置方法新版本(2)
    Oracle 创建时间维度表并更新是否工作日字段
  • 原文地址:https://www.cnblogs.com/fenice/p/5983073.html
Copyright © 2011-2022 走看看