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

由于这道题数字太大,我只写出了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");
	    }


	}

}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值