zoukankan      html  css  js  c++  java
  • hihocoder1489 Legendary Items 概率期望

    Little Hi is playing a video game. Each time he accomplishes a quest in the game, Little Hi has a chance to get a legendary item.

    At the beginning the probability is P%. Each time Little Hi accomplishes a quest without getting a legendary item, the probability will go up Q%. Since the probability is getting higher he will get a legendary item eventually.

    After getting a legendary item the probability will be reset to ⌊P/(2I)⌋% (⌊x⌋ represents the largest integer no more than x) where I is the number of legendary items he already has. The probability will also go up Q% each time Little Hi accomplishes a quest until he gets another legendary item.

    Now Little Hi wants to know the expected number of quests he has to accomplish to get N legendary items.  

    Assume P = 50, Q = 75 and N = 2, as the below figure shows the expected number of quests is

    2*50%*25% + 3*50%*75%*100% + 3*50%*100%*25% + 4*50%*100%*75%*100% = 3.25

    题意:要获取 N 个物品(1e6个),初始获得概率是 P %,每当上次没有获取,这次的获得概率会线性增加 Q%,直至达到 100% 则必定获取。而每当获取一个时,下一次的初始概率会下降,降低至 P / (2^l)%,l 是已经获取的个数,P 是之前给定的初始概率。问获取 N 个的期望次数是多少。

    这个题大概是微软的一道笔试题吧,貌似数据是随机的所以没有极限数据,我dfs+结论卡过去了一遍,后来又发现正解。

    由于后面的初始概率是按照已获取的个数定的,个数越多概率越小,由于题目最开始的 p 最大仅100,因此至多 7 层之后初始概率就都是 0 了。

    我最开始考虑当概率是 0 的时候,毫无疑问,每获取一个的次数期望都是固定的,我可以用一次循环直接求出这个期望次数。然后就通过类似图中的概率树的 dfs ,每当遇到一个下一次初始概率为 0 的位置时,就可以直接加上剩余需要获取的个数*获取每一个的期望,后面就不用 dfs 下去了。

    这种做法其实就可以通过这题的数据了。但是这样做通不过大数据,100 1 1000000

    当然,按照上述思路拓展一下,我们同样可以求出概率是任意值时获得下一个的期望,因为这个概率的范围只有 0~100 。其实我们发现图中那两个标号 1 的节点子树是一样的,它们获取下一个物品的情况和期望都是一样的。我本来在考虑不同情况下拿到第一个,开始拿第二个,第二个和第一个是不是独立的?但是其实所有情况下拿到第一个的概率总和是1,所以无论 dfs 的哪一个分支,最后都会到同一个初始概率去获取第二个,所以获取第二个的期望与第一个是独立可加的,所以我计算出所有初始概率下获取一个的期望,然后对于初始概率 P 跑一个循环,累计期望,然后计算下一次的初始概率,直到下一次的初始概率为 0 ,那么后面的就直接个数乘期望就能跳出循环了。

    因此这样做复杂度大概就是 O(100*100+7)

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<math.h>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 const int maxn=1e6+5;
     8 const int INF=0x3f3f3f3f;
     9 const int mod=1e9+7;
    10 double ans=0;
    11 double num[105] = {0};
    12 int n,p,q;
    13 
    14 int main(){
    15     scanf("%d%d%d",&p,&q,&n);
    16     for(int pre = 0 ; pre <= 100 ; ++ pre ){
    17         int cnt = 0;
    18         double p1 = 1;
    19         while(1){
    20             double xq = ( pre + cnt * q) / 100.0;
    21             if( pre + cnt * q >= 100 ){
    22                 num[pre] += ( cnt + 1 ) * p1 ;
    23                 break;
    24             }
    25             num[pre] += p1 * xq * ( cnt + 1 );
    26             p1 *= ( 1 - xq );
    27             cnt++;
    28         }
    29     }
    30 
    31     int pre = p;
    32     for(int i = 1 ; i <= n ; ++ i ){
    33         if( pre == 0 ){
    34             ans += ( n - i + 1 ) * num[0];
    35             break;
    36         }
    37         ans += num[pre];
    38         pre >>= 1;
    39     }
    40     
    41     printf("%.2lf
    ",ans);
    42     return 0;
    43 }
    View Code
  • 相关阅读:
    selenium-03-01截图函数
    selenium-03-02操作元素-等待
    [转]Linux下 tar.xz格式文件的解压方法
    selenium-05-问题2
    selenium-05-常见问题
    selenium-01-简介
    underscore
    前端底层-继承
    前端底层-面向对象3
    前端底层-面向对象2
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/6703253.html
Copyright © 2011-2022 走看看