codeforces 623d birthday

来源:互联网 发布:php初学者开发工具 编辑:程序博客网 时间:2024/06/06 11:42

译者:

翻译自http://kmjp.hatenablog.jp/entry/2016/02/10/0930

  这题不会做,又百度不出题解,谷歌了一下,找到了一份日文题解,讲的很明白。

        他给的那道类似题还没看- -放假了懒得不行- -

        最后我是把轮数设成2*10^5过的,10^6wa掉了,不知道是为什么

        我的代码:

#define _CRT_SECURE_NO_WARNINGS#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<iostream>#include<vector>#include<queue>using namespace std;const int maxn = 200006;typedef double ld;int n;ld p[105],g = 1;ld dp[105];int main(){cin >> n;for (int i = 0; i < n; i++) {scanf("%lf", &p[i]);p[i] /= 100;g *= p[i];dp[i] = p[i];}ld ret = n*g;for (int i = n + 1; i < maxn; i++){int x = 0;for (int j = 0; j < n; j++){if ((1 - dp[x])*p[x] * dp[j] < (1 - dp[j])*p[j] * dp[x]) x = j;}ld k=(dp[x]+(1-dp[x])*p[x])*g/dp[x];dp[x] += (1 - dp[x]) * p[x];ret += i * (k - g);g = k;}printf("%.10lf\n", ret);return 0;}

翻译的部分:

类似的题目:http://yukicoder.me/problems/483


题意:玩游戏有n个人,每轮随机抓一个人,猜这个人是谁,不知道是否猜中,然后进行下一轮,第i个人被抓住的概率是p[i],当所有人都被猜中一遍后,游戏结束。猜的人希望游戏进行的轮数越少越好

问猜人的这个人采取最优策略的情况下,游戏进行的轮数的期望是多少


题解:

设到第x轮为止,已经猜中过第i个人的概率为F(x,i)。

设所有人到第x轮为止已经全部被猜中过的概率G(x) = π(F(x,i))  (i=1,2,3....n)

第x轮对期望的贡献则为x*(G(x)-G(x-1))

(因为正好在第x轮结束游戏的概率为G(x)-G(x-1))

随轮数增长,G(x)会趋近与1

要让期望最小,显然在x越小的时候(G(x)-G(x-1))越大越好,即G(x)增长得越快越好


这样的话,若在第x轮猜测被抓到的是k,那么 F(x,k)=F(x-1,k)+(1-F(x-1,k))*P[k],F(x,i)=F(x-1,i)  (i != k)

G(x)=G(x-1)*(F(x,k))/F(x-1,k)

因此每次选择k时选择F(x,k)/F(x-1,k)最大的,即  (1-F(x-1,k))*P[k]/F(x-1,k)最大的

接下来只要将上述过程模拟到10^6就好


1 1