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

题意:

  一次ACM比赛,有t支队伍,比赛共m道题。

  第i支队伍做出第j道题的概率为p[i][j].

  问你所有队伍都至少做出一道,并且有队伍做出至少n道的概率。

题解:

  关于【至少】问题的表示。

  

  对于每一支队伍:

    mst[i][j] = P(第i支队伍做出至多j道题)

    则 P(第i支队伍做出至少j道题) = 1 - mst[i][j-1]

  

  对于所有队伍:

    P(所有队伍至少答出一题) = ∏ (1 - mst[i][0])

    P(所有队伍答题数在1到n-1) = ∏ (mst[i][n-1] - mst[i][0])

    所以答案:

    P(所有队伍至少答出一题,且有队伍做出至少n道) = P(所有队伍至少答出一题) - P(所有队伍答题数在1到n-1)

  所以求mst数组好啦~~~

  dp[i][j][k] = probability

  i:第i支队伍

  j:考虑到前j道题(包含j)

  k:恰好做出k道

  所以 mst[i][j] = sigma(dp[i][m][0 to j])

  怎么求dp数组呢:

    转移:dp[i][j][k] = dp[i][j-1][k-1]*p[i][j] + dp[i][j-1][k]*(1-p[i][j])

    边界:dp[i][0][0] = 1, others = 0

  所以这道题:先求dp,再求mst,最后统计ans。

AC Code:

 // state expression:
// dp[i][j][k] = probability
// i: ith team
// j: jth question and before
// k: solved k questions
// mst[i][j]
// i: ith team
// j: all the teams solved at most j questions
//
// find the answer:
// P(all 1 to m) - P(all 1 to n-1)
//
// transferring:
// dp[i][j][k] = dp[i][j-1][k-1]*p[i][j] + dp[i][j-1][k]*(1-p[i][j])
//
// boundary:
// dp[i][0][0] = 1
// others = 0
//
// calculate:
// mst[i][j] = sigma dp[i][m][0 to j]
// P1 = pi (1 - mst[i][0])
// P2 = pi (mst[i][n-1] - mst[i][0])
//
// step:
// 1) cal dp
// 2) cal mst
// 3) cal ans
#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX_T 1005
#define MAX_N 35
#define MAX_M 35 using namespace std; int n,m,t;
double p1,p2;
double p[MAX_T][MAX_M];
double dp[MAX_T][MAX_M][MAX_M];
double mst[MAX_T][MAX_M]; void read()
{
for(int i=;i<=t;i++)
{
for(int j=;j<=m;j++)
{
cin>>p[i][j];
}
}
} void cal_dp()
{
memset(dp,,sizeof(dp));
for(int i=;i<=t;i++)
{
dp[i][][]=;
for(int j=;j<=m;j++)
{
for(int k=;k<=m;k++)
{
if(k->=) dp[i][j][k]+=dp[i][j-][k-]*p[i][j];
dp[i][j][k]+=dp[i][j-][k]*(-p[i][j]);
}
}
}
} void cal_mst()
{
// mst[i][j] = sigma dp[i][m][0 to j]
memset(mst,,sizeof(mst));
for(int i=;i<=t;i++)
{
for(int j=;j<=m;j++)
{
for(int k=;k<=j;k++)
{
mst[i][j]+=dp[i][m][k];
}
}
}
} void cal_ans()
{
// P1 = pi (1 - mst[i][0])
// P2 = pi (mst[i][n-1] - mst[i][0])
p1=1.0;
p2=1.0;
for(int i=;i<=t;i++)
{
p1*=(-mst[i][]);
p2*=(mst[i][n-]-mst[i][]);
}
} void solve()
{
cal_dp();
cal_mst();
cal_ans();
} void print()
{
printf("%.3f\n",p1-p2);
} int main()
{
while(cin>>m>>t>>n)
{
if(m== && t== && n==) break;
read();
solve();
print();
}
}

POJ 2151 Check the difficulty of problems:概率dp【至少】的更多相关文章

  1. POJ 2151 Check the difficulty of problems 概率dp+01背包

    题目链接: http://poj.org/problem?id=2151 Check the difficulty of problems Time Limit: 2000MSMemory Limit ...

  2. [ACM] POJ 2151 Check the difficulty of problems (概率+DP)

    Check the difficulty of problems Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4748   ...

  3. POJ 2151 Check the difficulty of problems (概率DP)

    题意:ACM比赛中,共M道题,T个队,pij表示第i队解出第j题的概率 ,求每队至少解出一题且冠军队至少解出N道题的概率. 析:概率DP,dp[i][j][k] 表示第 i 个队伍,前 j 个题,解出 ...

  4. POJ 2151 Check the difficulty of problems (动态规划-可能DP)

    Check the difficulty of problems Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4522   ...

  5. POJ 2151 Check the difficulty of problems

    以前做过的题目了....补集+DP        Check the difficulty of problems Time Limit: 2000MS   Memory Limit: 65536K ...

  6. poj 2151 Check the difficulty of problems(概率dp)

    poj double 就得交c++,我交G++错了一次 题目:http://poj.org/problem?id=2151 题意:ACM比赛中,共M道题,T个队,pij表示第i队解出第j题的概率 问 ...

  7. POJ 2151 Check the difficulty of problems (概率dp)

    题意:给出m.t.n,接着给出t行m列,表示第i个队伍解决第j题的概率. 现在让你求:每个队伍都至少解出1题,且解出题目最多的队伍至少要解出n道题的概率是多少? 思路:求补集. 即所有队伍都解出题目的 ...

  8. [POJ2151]Check the difficulty of problems (概率dp)

    题目链接:http://poj.org/problem?id=2151 题目大意:有M个题目,T支队伍,第i个队伍做出第j个题目的概率为Pij,问每个队伍都至少做出1个题并且至少有一个队伍做出N题的概 ...

  9. POJ2157 Check the difficulty of problems 概率DP

    http://poj.org/problem?id=2151   题意 :t个队伍m道题,i队写对j题的概率为pij.冠军是解题数超过n的解题数最多的队伍之一,求满足有冠军且其他队伍解题数都大于等于1 ...

随机推荐

  1. PS中混合模式是什么意思?

      PS中图层混合模式中的溶解,变暗,正片叠底,颜色加深,线性加深,叠加,柔光,亮光,强光,线性光,点光,实色混合,差值,排除,色相,饱和度,颜色,亮度各是什么原理?   Normal 正常模式,也是 ...

  2. apue学习笔记(第九章 进程关系)

    本章将详细地说明进程组以及POSIX.1引入的会话的概念.还将介绍登录shell和所有从登录shell启动的进程之间的关系 终端登录 BSD终端登录.系统管理者创建通常名为/etc/ttys的文件,其 ...

  3. C++里面定时器的使用

    说白了就是三个函数的使用: SetTimer(20, 20, 0); //第一个20表示此定时器的标识符,第二个20表示你要定的时间,第三个不用管,设0即可. void CLMS511_interfa ...

  4. jquery方法

    $.inArray(被判断的量,ArrayName);  如果存在返回索引值,如果不存在返回-1 $.unique() 数组去重   根据去重前后的长度,判断是否有重复 $.each(被遍历的数组,f ...

  5. Node.js学习笔记(5)——关于child_process模块

    child_process是node一个比较重要的模块,通过它可以实现创建多线程,来利用多核CPU. 这个模块提供了四个创建子进程的函数. spawn.exec.execFile.fork. spaw ...

  6. VueJS字符串反转:String.reverse()

    HTML <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <titl ...

  7. StringBuilder作用

    String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然 ...

  8. Struts2学习三----------Action搜索顺序

    © 版权声明:本文为博主原创文章,转载请注明出处 Struts2的Action的搜索顺序 http://localhost:8080/path1/path2/student.action 1)判断pa ...

  9. cocos2dx中使用iconv转码(win32,iOS,Android)

    首先贴下环境:Win7 64, NDK r8e, libiconv-1.14, cygwin 一 Win32环境配置 Cocos2D-X自带有win32上的iconv库.仅仅须要配置一下就可以使用. ...

  10. 兔子--改动Android Studio的快捷键,改动成eclipse的快捷键

    仅仅须要2步 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzQyNTUyNw==/font/5a6L5L2T/fontsize/400/fill ...