codeforces 623D
2016-04-15 14:41
369 查看
原题
原题链接题目大意
给定n≤100n\leq100个人,每轮随机选取一个人,每个人被选的概率为pi(精度为0.01),∑pi=1p_i(精度为0.01),\sum p_i=1,游戏结束当且仅当每个人被抓住一次或以上,问,在最优策略下,期望结束轮数是多少,要求答案精度为10−610^{-6}。解题思路
设fi,jf_{i,j}表示第ii轮结束之后,第jj个人被抓过的概率。设gig_i表示第ii轮结束之后,所有人都被抓过的概率。
显然gi=∏nj=1fi,jg_i=\prod_{j=1}^{n} f_{i,j}.
∵Ans=∑+∞i=1i∗(gi−gi−1)\because Ans=\sum_{i=1}^{+\infty} i*(g_i-g_{i-1})
∴\therefore最优策略就是,尽量使得ii较小时,gi−gi−1g_i-g_{i-1}较大。
先看看fi,jf_{i,j}和fi−1,jf_{i-1,j}的关系。
1)fi,j=fi−1,j1)f_{i,j}=f_{i-1,j},第ii轮不选jj.
2)fi,j=fi−1,j+(1−fi−1,j)∗pj2)f_{i,j}=f_{i-1,j}+(1-f_{i-1,j})*p_j,第ii轮选jj.
∴gi=gi−1∗fi,j/fi−1,j\therefore g_i=g_{i-1}*f_{i,j}/f_{i-1,j}
只要求fi,j/fi−1,jf_{i,j}/f_{i-1,j}最大即可,这个可以枚举,或者用数据结构维护。
其实3∗1053*10^5轮过后答案就不会再有大于10−610^{-6}的误差了。
误差分析
gt≥ (1−0.99t/100)100 ≥1−100⋅0.99t / 100.g_t\geq (1-0.99^{t/100})^{100} \geq1-100·0.99^{t / 100}.∑+∞t=N+11−gt≤100∗∑+∞t=N+10.99t/100\sum_{t=N+1}^{+\infty} 1-g_t\leq100*\sum_{t=N+1}^{+\infty}0.99^{t/100}.
所以大概3∗1053*10^5次运算之后答案就精准了。
参考代码
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) #define maxn 105 #define lim 300000 #define ld long double #define mem(a,b) memset(a,b,sizeof(a)) #define eps 1e-15 using namespace std; ld f[2][maxn]; ld g[2],ans; ld p[maxn]; int n; int main(){ scanf("%d",&n); fo(i,1,n) { cin>>p[i]; p[i]/=100; } int last=0,now=1; fo(i,1,lim) { last^=1; now^=1; ld best=0; int w=0; fo(j,1,n) { ld thi=(1-f[last][j])*p[j]/f[last][j]; if (thi>best) { best=thi; w=j; } } fo(j,1,n) { if (j==w) { f[now][j]=f[last][j]+(1-f[last][j])*p[j]; } else { f[now][j]=f[last][j]; } } if (f[last][w]<eps) { g[now]=1; fo(j,1,n) g[now]=g[now]*f[now][j]; } else g[now]=g[last]*f[now][w]/f[last][w]; ans=ans+(g[now]-g[last])*i; } double pri=ans; printf("%.16lf",pri); return 0; }
相关文章推荐
- MERGE INTO语法
- 编译器判断优化(__builtin_expect)
- 行内元素与块级函数的三个区别
- 配置centos防火墙(iptables)开放80端口
- C#:OleDbDataAdapter 进行增,删,改,查操作
- IO简单总结
- 流量描述统计及频率分布(Python版)
- 广告访问量平均数差异的显著性检验
- 求二进制中1的个数
- nginx + gevent + django高并发配置
- Ubuntu14.04下KLEE的安装教程和使用KLEE分析GNC代码的教程
- Android开发,关于依赖库和JAR包的区别以及使用多个依赖库可能出现的问题(SlidingMenu、SwipeBackLib)
- 关于J2EE/EJB/Spring
- Routine
- Android头像选择(手机和相册)
- Swift - 按钮(UIButton)的用法
- 多台服务器共享session
- SSH免密码登录
- 引用iBatis中oscache实现自定义缓存及动态更新技巧
- SSH整合过程中中文乱码问题的解决方案(以mysql数据库为简单案例)