【POJ 2151】Check the difficulty of problems
2015-08-05 16:51
363 查看
【POJ 2151】Check the difficulty of problems
明明是道概率dp 训练计划里却赤果果放在了hash+二分里。。。。shenmegui
不过强行把概率dp给整了出来。。自己瞎捣鼓居然捣鼓出来了
T支队伍每支队伍都要解M道题 问每只队伍至少解1道并且解答最多的队伍要解N道以上的概率是多少
直接做很难 可以用补集
P(AllTeam >= 1 && MaxTeam >= N) = 1 - P(HasTeam < 1 || AllTeam < N)
开一个数组 存放对应解题数的概率
dp后分别找出HasTeam<1 || AllTeam < N的概率即可求出答案
我们发现 两边存在重叠 可以合并为P(HasTeam < 1) + P(0 < AllTeam < N)
0 < AllTeam < N 就是所有队伍1~N+1的所有组合乘积
假设T = 2 N = 4
team1解决1题概率为a 解决两题为b 三题为c
team2解决1题概率为A 解决两题为B 三题为C
显然 P(0 < AllTeam < N) = a*A + b*A + c*A + a*B + b*B + c*B + a*C + b*C + c*C = (a+b+c)*(A+B+C)
同样对于多个队伍来说也是如此 故可推出 P(0 < AllTeam < N) = 每只队伍各自解1~n-1个题的累加 然后把每只队伍各自的加和累乘
求P(HasTeam < 1)又会发现 如果和上面一样求法会出现重叠 p1*p2在后面又会出现p2*p1 所以同样再用一次补集 P(HasTeam < 1) = 1 - P(NoTeam < 1)
P(NoTeam < 1) = team 1->T (1-dp[0])累乘
准备工作都做完后便可直接求出结果
P(AllTeam >= 1 && MaxTeam >= N)
= 1 - P(HasTeam < 1 || AllTeam < N)
= 1 - (P(HasTeam < 1) + P(1 < AllTeam < N))
= 1 - ((1 - P(NoTeam < 1)) + P(1 < AllTeam < N))
= P(NoTeam < 1) - P(1 < AllTeam < N)
给的时间范围时2000ms 本想开个输入外挂强行装一发。。结果写的太搓没过TOT 哪位大牛帮忙瞅瞅~
代码如下:
明明是道概率dp 训练计划里却赤果果放在了hash+二分里。。。。shenmegui
不过强行把概率dp给整了出来。。自己瞎捣鼓居然捣鼓出来了
T支队伍每支队伍都要解M道题 问每只队伍至少解1道并且解答最多的队伍要解N道以上的概率是多少
直接做很难 可以用补集
P(AllTeam >= 1 && MaxTeam >= N) = 1 - P(HasTeam < 1 || AllTeam < N)
开一个数组 存放对应解题数的概率
for i 1->T //第i队伍 { for j 1->M //第j题 { for k j->0 //j限制了最大解题数 if(k==0) dp[k] *= (1-p[j]); //1题没解 = 1-p[j]累乘 else dp[k] = dp[k]*(1-p[j]) + dp[k-1]*p[j] } }
dp后分别找出HasTeam<1 || AllTeam < N的概率即可求出答案
我们发现 两边存在重叠 可以合并为P(HasTeam < 1) + P(0 < AllTeam < N)
0 < AllTeam < N 就是所有队伍1~N+1的所有组合乘积
假设T = 2 N = 4
team1解决1题概率为a 解决两题为b 三题为c
team2解决1题概率为A 解决两题为B 三题为C
显然 P(0 < AllTeam < N) = a*A + b*A + c*A + a*B + b*B + c*B + a*C + b*C + c*C = (a+b+c)*(A+B+C)
同样对于多个队伍来说也是如此 故可推出 P(0 < AllTeam < N) = 每只队伍各自解1~n-1个题的累加 然后把每只队伍各自的加和累乘
求P(HasTeam < 1)又会发现 如果和上面一样求法会出现重叠 p1*p2在后面又会出现p2*p1 所以同样再用一次补集 P(HasTeam < 1) = 1 - P(NoTeam < 1)
P(NoTeam < 1) = team 1->T (1-dp[0])累乘
准备工作都做完后便可直接求出结果
P(AllTeam >= 1 && MaxTeam >= N)
= 1 - P(HasTeam < 1 || AllTeam < N)
= 1 - (P(HasTeam < 1) + P(1 < AllTeam < N))
= 1 - ((1 - P(NoTeam < 1)) + P(1 < AllTeam < N))
= P(NoTeam < 1) - P(1 < AllTeam < N)
给的时间范围时2000ms 本想开个输入外挂强行装一发。。结果写的太搓没过TOT 哪位大牛帮忙瞅瞅~
代码如下:
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> using namespace std; double pm[1111][33],dp[33]; double read() { double x = 0,p = 0.1; char ch = ' '; while(ch < '0' || ch > '9') ch = getchar(); while(ch >= '0' && ch <= '9') x = x*10+ch-'0',ch = getchar(); if(ch != '.') return x; ch = getchar(); while(ch >= '0' && ch <= '9') x += (ch-'0')*p,p*=0.1,ch = getchar(); return x; } int main() { int i,j,k,m,n,t; double p,sd,zer; while(~scanf("%d %d %d",&m,&t,&n) && m) { p = zer = 1; for(i = 0; i < t; ++i) { for(j = 0; j < m; ++j) scanf("%lf",&pm[i][j]);//pm[i][j] = read(); } for(i = 0; i < t; ++i) { memset(dp,0,sizeof(dp)); sd = 0; dp[0] = 1; for(j = 0; j < m; ++j) { for(k = min(j+1,n+1); k >= 0; --k) { if(!k) dp[k] *= (1-pm[i][j]); else dp[k] = (1-pm[i][j])*dp[k]+dp[k-1]*pm[i][j]; } } for(j = 1; j < n; ++j) sd += dp[j]; p *= sd; zer *= 1-dp[0]; } printf("%.3lf\n",zer-p); } return 0; }
相关文章推荐
- Web API with OAuth2.0
- Collection集合的总结以及如果选择适合的集合(包括对List和Set的对比)
- 使用CSS绘制星级评分效果的方法
- 一个简单了解spring的例子
- java正则表达式特殊字符转义
- CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\e6148660
- system.h
- hdu 1728 逃离迷宫
- 学院,系别,班级,学生XXX.hbm.xml配置
- POJ 3069 Saruman's Army
- [SD.TEAM语录]AC语录
- effetive C++ 02 尽量以const,enum,inline替换#define
- C++ primer plus 练习11
- viewPaper 判断是否是最后一页继续滑动的操作
- 如何加密Web项目中配置文件中的密码?
- Android图像处理之Bitmap类(1)
- js function的displayNama属性
- AOP和IoC实现原理【用到的设计模式】
- iOS 百度地图开发集成使用 (转)
- Android Service把值传给Activity