码迷,mamicode.com
首页 > 其他好文 > 详细

hihocoder1489 Legendary Items 概率期望

时间:2017-04-13 12:47:04      阅读:447      评论:0      收藏:0      [点我收藏+]

标签:integer   std   tin   ++   gen   复杂   opened   one   ber   

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\n",ans);
42     return 0;
43 }
View Code

 

hihocoder1489 Legendary Items 概率期望

标签:integer   std   tin   ++   gen   复杂   opened   one   ber   

原文地址:http://www.cnblogs.com/cenariusxz/p/6703253.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!