HDU 5245 joyful( 2015 Shanghai Metropolitan J )

【題目鏈接】
http://acm.hdu.edu.cn/showproblem.php?pid=5245

【解題報告】
題目大意:給你一個N*M個格子的矩陣,每次任意挑兩個格子(可以相同)染色,一共染色K次,求被染色的格子的個數的期望。
一道普通概率題,解題關鍵在於

如何求一個格子在k次染色後不被染色的期望。

現在我們來算第(i,j)個格子不被取中的概率
這裏寫圖片描述
易知
S1=(i-1)^2*N^2;
S2=(N-j)^2*M^2;
其中S3=(i-1)^2*( N-j )^2被算了兩次,所以需要被減去一次。

如果我們知道一個格子被染色的期望爲P(i,j)
即第(i,j)個格子裏有P(i,j)的部分被染色了。
那麼累加所有格子的染色期望我們就能知道一個矩陣在K次染色後可能有多少個格子被染色。

另外,在計算過程中可能會爆int( 500^4 ),所以需要用long long來處理

【參考代碼】

#include<cstdio>
#include<iostream>
using namespace std;

long long M,N,K;

long long C( int num )
{
    return (long long)num*(long long)num;
}

long long cal( long long i, long long j )
{
    long long ans=0;
    ans+= C(N*(i-1)) + C(N*(M-i)) + C(M*(j-1)) + C(M*(N-j));
    ans-= C((i-1)*(j-1)) + C((i-1)*(N-j)) + C((M-i)*(j-1)) + C((M-i)*(N-j));
    return ans;
}

double pow_mod( double P, long long K )
{
    double ans=1.0;
    while(K)
    {
        if(K&1)ans*=P;
            P*=P;
        K/=2;
    }
    return ans;
}

int main()
{
    int T,kase=0;
    cin>>T;
    while(T--)
    {
        scanf("%I64d%I64d%I64d",&M,&N,&K);
        long long all=M*M*N*N;
        double ans=0.0;
        for( long long i=1; i<=M; i++ )
        for( long long j=1; j<=N; j++ )
        {
            double P=cal(i,j)*1.0/(all*1.0);
            ans+=1-pow_mod( P, K );
        }
        printf("Case #%d: %d\n", ++kase,(int)(ans+0.5) );
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章