POJ - 2151 检查问题的困难度 动态规划

输入数据格式:

问题数M,队伍数T,冠军至少答出N

每个队伍占一行,表示每个题目解出来的概率

组合数学中的集合问题

一个队解出来至少N个题且其他队至少解出来1个题

=每个队至少解1个题-每个队都解了1到N-1个题

动态规划

三维状态转移方程dp[i][j][k]第i个队前j道题解出来k个的概率

递推过程:dp[i][j][k] = dp[i][j-1][k]*(1-p[j-1]) + dp[i][j-1][k-1]*p[j-1]; 第一项表示第j道没有解出来,第二项表示第j道解出来了

注意输出格式三个小数点,C语言保留小数点后几位,不要的直接舍弃,但是C++会四舍五入,所以要用C语言的printf,否则会WA

#include<iostream>

using namespace std;

const int maxT = 1010;
const int maxM = 35;
double dp[maxT][maxM][maxM];
double p[maxM];

int main()
{
    int T,M,N;
    while(cin>>M>>T>>N){
        if(!M&&!T&&!N)break;
        for(int i=0;i<T;i++){
            for(int m=0;m<M;m++)cin>>p[m];
            dp[i][0][0] =1;
            for(int j=1;j<=M;j++)dp[i][j][0] = dp[i][j-1][0]*(1-p[j-1]);
            for(int k=1;k<=M;k++)dp[i][0][k] = 0;
            for(int j=1;j<=M;j++){
                for(int k=1;k<=M;k++){
                    dp[i][j][k] = dp[i][j-1][k]*(1-p[j-1]) + dp[i][j-1][k-1]*p[j-1];
                }
            }
        }

        double s0 = 1;
        for(int i=0;i<T;i++){
            double s1 = 0;
            for(int k=1;k<=M;k++)s1+=dp[i][M][k];
            s0*=s1;
        }

        double s2 = 1;
        for(int i=0;i<T;i++){
            double s3 = 0;
            for(int k=1;k<=N-1;k++)s3+=dp[i][M][k];
            s2*=s3;
        }
        double prob = s0 - (s2);
        printf("%.3f\n", prob);
    }
    return 0;
}

 

发布了101 篇原创文章 · 获赞 12 · 访问量 3万+
展开阅读全文

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

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览