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.
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)
For each n, output the expected days to collect all the n kinds of cards, rounded to one decimal place.
4 1 2 5 9Sample Output
1.0 3.0 274.0 1026576.0
由于这道题数字太大,我只写出了c++小数版代码,然后由队友改成java大数版。
思路:
假设现在已经有k种卡牌,得到k+1种的概率为(k+1)/n*w
那么要达到k+1,期望为w*n/(k+1).最终公式就显然了.
其实这是一道经典,期望题的变形题,原来那道题没有权值w。
c++ 小数代码:(提交肯定不对,但求解方法与java类似)
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int jie(int x)
{
int sum=1;
for(int i=1;i<=x;i++)
{
sum=sum*i;
}
return sum;
}
double qi(int x)
{
double sum=0;
for(double i=1;i<=x;i++)
{
sum+=1/i;
}
return sum;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int sum1=jie(n);
double sum2=qi(n);
printf("%.1f\n",sum1*sum2);
}
return 0;
}
java大数版
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
static BigInteger jie(int x)
{
BigInteger sum= BigInteger.ONE;
for(int i=1;i<=x;i++)
{
BigInteger z= BigInteger.valueOf(i);
sum=sum.multiply(z);
}
return sum;
}
public static void main(String[] args) {
int t=0;;
Scanner cin=new Scanner(System.in);
t=cin.nextInt();
for(int k=0;k<t;k++)
{
int n;
n=cin.nextInt();
BigInteger ans=BigInteger.ZERO;
BigInteger sum1=jie(n);
for(int i=1;i<=n;i++){
ans=ans.add(sum1.divide(BigInteger.valueOf(i)));
}
System.out.println(ans+".0");
}
}
}