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
借鉴理解的原文
我们假设已经有了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=各个单独事件的期望和;
那么Ans=Σn!/i(1<=i<=n)
我们预处理出来n!,这样求一个就可以在o(n)的时间范围。
import java.math.BigInteger;
import java.math.BigDecimal;
import java.util.Scanner;
class Main{
public static void main(String[] arges){
Scanner cin=new Scanner(System.in);
BigInteger[] k=new BigInteger[3000+10];
k[0] = BigInteger.ONE;
for(int i=1;i<=3000+2;i++){
k[i]=k[i-1].multiply(new BigInteger(""+i));
}
int t ;t=cin.nextInt();
while(t-->0){
BigInteger ans=BigInteger.ZERO;
int n;n=cin.nextInt();
for(int i=1;i<=n;i++){
ans=ans.add(k[n].divide(new BigInteger(""+i)));
}
System.out.println(ans+".0");
}
}
}