YYS FZU - 2278 (概率期望+大数)

YYS

FZU - 2278

Yinyangshi is a famous RPG game on mobile phones.

Kim enjoys collecting cards in this game. Suppose there are n kinds of cards. If you want to get a new card, you need to pay W coins to draw a card. Each time you can only draw one card, all the cards appear randomly with same probability 1/n. Kim can get 1 coin each day. Suppose Kim has 0 coin and no cards on day 0. Every W days, Kim can draw a card with W coins. In this problem ,we define W=(n-1)!.

Now Kim wants to know the expected days he can collect all the n kinds of cards.


Input

The first line an integer T(1 ≤ T ≤ 10). There are T test cases.

The next T lines, each line an integer n. (1≤n≤3000)

Output

For each n, output the expected days to collect all the n kinds of cards, rounded to one decimal place.

Sample Input
4
1
2
5
9
Sample Output
1.0
3.0
274.0
1026576.0

题目大意:

我们现在想要收集到n个卡片,现在已知抽到每种卡片的概率为1/n;

我们每隔(n-1)!天就可以进行一次抽奖。

问收集齐所有卡片的期望天数。


此题有两种理解方式:

1.

我们假设已经有了a张卡片的话,如果我们想要得到第a+1张,我们抽中他的概率显然就是(n-a)/n,只要我们得到除了这a张卡片的任意一张即可。那么从a张卡片变成a+1张卡片的期望抽奖次数是多少呢?


我们考虑这样一个问题,假设我们抽奖中奖的概率为1/4,那么期望中奖的抽奖次数是多少呢?显然是1/(1/4)=4.


那么回归到当前问题,如果我们已经有了a张卡片,想要得到第a+1张,我们抽中一张新的卡片概率很显然是(n-a)/n,那么期望进行的次数就是n/(n-a);


将这个问题分成n个独立事件去考虑,那么总期望E=各个单独事件的期望和;

得到了每一个期望次数,因为每隔W即(n-1)!天才能抽一次,所以天数就是E(m)*W

所以      

        

第二种理解方式很具有说服力,用公式推导,但是说实话我没有理解第一个求k + 1张未抽到过的卡片的期望次数的公式,但是下面通过等比数列求和,然后取极限也得到了上面的式子(当然非常希望有大神帮忙解释一下下面第一个公式的第一行的意义

思路: 假设共有n张卡片, 已经抽到了k张不同的卡片, 则抽第k + 1张未抽到过的卡片的期望次数:

     

所以花费金币的期望:

         

 

所以预处理一下n <= 3000的阶乘, 即可在O(n)时间内求出期望,由于n <= 3000, n! 太大, 所以用Java的BigInteger计算比较方便

code:

import java.util.Scanner;
import java.math.*;
public class Main{
	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		BigInteger[] b = new BigInteger[4000];
		b[0] = new BigInteger("1");
		for(int i = 1; i < 4000; i++) {
			String d = i + "";
			b[i] = b[i-1].multiply(new BigInteger(d));
		}
		int t = cin.nextInt();
		while(t-- > 0) {
			int n = cin.nextInt();
			BigInteger ans = new BigInteger("0");
			for(int i = 1; i <= n; i++) {
				ans = ans.add(b[n].divide(new BigInteger(i + "")));
			}
			System.out.print(ans);
			System.out.println(".0");
		}
	}
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值