POJ2151 Check the difficulty of problems 概率DP

版权声明:hhhhh https://blog.csdn.net/WT_cnyali/article/details/77621291

Description

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:
- All of the teams solve at least one problem.
- 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?

  • 题意
    M道题,T个队伍,给出所有队伍分别解出每个题的概率pij,求每个队至少解出1题且冠军队解出至少N题的概率。

  • 解析
    涉及到 至少 这个词,不妨使用一些前缀和技巧。
    假设p1是所有队都解出至多M题的概率,p2是所有队解出至多N1题的概率,那么最后的答案就是p1p2
    我们需要分别计算每一队的贡献,再把相应的答案乘起来从而计算p1p2
    f[i][j]代表当前是前i道题,解出了一共j道题的概率。不难发现转移方程为

    f[i][j]=f[i1][j1]×p[i][j]+f[i1][j]×(1p[i][j])

    再利用sum[i]代表所有题中解出至多i道题的概率,其实就是前缀和。
    那么这个队对于p1的贡献就是sum[M]sum[0]p2的贡献是sum[N1]sum[0]

  • 数组可以滚,你不滚也没关系

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <map>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <algorithm>
#include <cctype>
#include <string>
using namespace std ;
const int maxn = 1005, maxm = 35 ;
int n, m, e ;
double p[maxm], f[2][maxm], sum[maxm] ;
int main() {
    int i, j, k ;
    while ( scanf ( "%d %d %d", &m, &n, &e ) != EOF ) {
        if ( !n ) break ;
        double p1 = 1.0, p2 = 1.0 ;
        for ( i = 1 ; i <= n ; i ++ ) {
            for ( j = 1 ; j <= m ; j ++ )
                scanf ( "%lf", &p[j] ) ;
            memset ( f, 0.0, sizeof f ) ;
            int u, v ;
            u = 0, v = 1 ;
            memset ( f, 0.0, sizeof f ) ;
            f[0][0] = 1.0 ;
            for ( j = 1 ; j <= m ; j ++, swap(u, v) )
                for ( k = 0 ; k <= j ; k ++ )
                    f[v][k] = f[u][k-1]*p[j]+f[u][k]*(1-p[j]) ;
            sum[0] = f[u][0] ;
            for ( j = 1 ; j <= m ; j ++ )
                sum[j] = sum[j-1]+f[u][j] ;
            p1 *= sum[m]-sum[0] ;
            p2 *= sum[e-1]-sum[0] ;
        }
        printf ( "%.3lf\n", p1-p2 ) ;
    }
    return 0 ;
}

Check the difficulty of problems

10-06

DescriptionnnOrganizing 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: n1. All of the teams solve at least one problem. n2. The champion (One of those teams that solve the most problems) solves at least a certain number of problems. nnNow 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. nnGiven 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? nInputnnThe 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.nOutputnnFor each test case, please output the answer in a separate line. The result should be rounded to three digits after the decimal point.nSample Inputnn2 2 2n0.9 0.9n1 0.9n0 0 0nSample Outputnn0.972

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试