HDU 5810 Balls and Boxes(打表找规律)——2016 Multi-University Training Contest 7 1002

传送门

(Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 43    Accepted Submission(s): 32


Problem Description
Mr. Chopsticks is interested in random phenomena, and he conducts an experiment to study randomness. In the experiment, he throws n balls into m boxes in such a manner that each ball has equal probability of going to each boxes. After the experiment, he calculated the statistical variance V as
V=mi=1(XiX¯)2m

where Xi is the number of balls in the ith box, and X¯ is the average number of balls in a box.
Your task is to find out the expected value of V.
 

Input
The input contains multiple test cases. Each case contains two integers n and m (1 <= n, m <= 1000 000 000) in a line.
The input is terminated by n = m = 0.
 

Output
For each case, output the result as A/B in a line, where A/B should be an irreducible fraction. Let B=1 if the result is an integer.
 

Sample Input
    
    
    
    
2 1
2 2
0 0
 

Sample Output
    
    
    
    
0/1
1/2

Hint

题目大意:

给出 n 个球 m 个箱子,让你求上述公式的方差的期望。

解题思路:

我的思路就是打个表,找一下规律,就可以了,我们推公式推到

ans=ni=0Cin(m1)nii2mnn2m2

然后再往下就推不出来了, 一怒之下打表,过了公式很简单:

n(m1)m2

官方题解:

E[V]=E[mi=1(XiX¯)2m]=E[(XiX¯)2]=E[X2i2XiX¯+X¯2]

=E[X2i]2X¯E[Xi]+E[X¯2]=E[X2i]2X¯2+X¯2=E[X2i]n2m2

所以关键是要求出 E[X2i] . 我们用随机变量 Yj 来表示第j个球是否在第i个盒子中,如果在则

Yj=1 ,否则 Yj=0 . 于是

E[X2i]=E[(nj=1Yj)2]=E[nj=1Y2j]+2E[nj=1nk=1,kjYjYk]=nE[Y2j]+n(n1)E[YjYk]

=nm+n(n1)m2

因此,

E[V]=nm+n(n1)m2n2m2=n(m1)m2

出题人真实太厉害了!!!;

My Code

/**
2016 - 08 - 09 晚上
Author: ITAK

Motto:

今日的我要超越昨日的我,明日的我要胜过今日的我,
以创作出更好的代码为目标,不断地超越自己。
**/

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 1e9+5;
const int MAXN = 1e6+5;
const int MOD = 1e9+7;
const double eps = 1e-7;
const double PI = acos(-1);
using namespace std;
LL GCD(LL a, LL b)
{
    if(b == 0)
        return a;
    return GCD(b, a%b);
}
LL c[50][50];
void Init()
{
    for(int i=0; i<50; i++)
        c[i][0] = 1;
    for(int i=1; i<50; i++)
        for(int j=1; j<50; j++)
            c[i][j] = (c[i-1][j]+c[i-1][j-1]);
}
LL get(LL m, LL n)
{
    LL ans = 1;
    for(int i=1; i<=n; i++)
        ans*=m;
    return ans;
}
int main()
{
    Init();
    LL n, m;
    while(~scanf("%I64d%I64d",&n,&m))
    {
        if(!n && !m)
            break;
        if(m == 1LL)
        {
            puts("0/1");
            continue;
        }
        /**打表 找规律**/
        /**
        LL ans = 0;
        for(int i=0; i<=n; i++)
        {
            ans += (c[n][i]*get(m-1,n-i)*i*i);
        }
        LL tmp = get(m, n);
        LL d = GCD(ans, tmp);
        cout<
        LL tm = n*(m-1);
        LL tn = m*m;
        LL d = GCD(tm, tn);
        printf("%I64d/%I64d\n",tm/d,tn/d);
    }
    return 0;
}

你可能感兴趣的:(ACM_数论,ACM_HDU,Multi,ITAK的ACM之路)