1. 程式人生 > >HDU 5245 染色問題(數學期望)

HDU 5245 染色問題(數學期望)

Joyful

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 478    Accepted Submission(s): 209

Problem Description

Sakura has a very magical tool to paint walls. One day, kAc asked Sakura to paint a wall that looks like an matrix. The wall has squares in all. In the whole problem we denotes to be the square at the -th row, -th column. Once Sakura has determined two squares and , she can use the magical tool to paint all the squares in the sub-matrix which has the given two squares as corners.

However, Sakura is a very naughty girl, so she just randomly uses the tool for times. More specifically, each time for Sakura to use that tool, she just randomly picks two squares from all the squares, with equal probability. Now, kAc wants to know the expected number of squares that will be painted eventually.

Input

The first line contains an integer(), denoting the number of test cases.

For each test case, there is only one line, with three integers and .
It is guaranteed that ,.

Output

For each test case, output ''Case #t:'' to represent the-th case, and then output the expected number of squares that will be painted. Round to integers.

Sample Input

2 3 3 1 4 4 2

Sample Output

Case #1: 4 Case #2: 8

題目大意是給定一個m*n的矩陣,每次選擇一個隨機選擇子矩陣進行染色,問k次染色後,被染色格子數目的期望值。

思路:染色格子數的期望值=每個格子被染色的概率和,所以先把一個格子被染色的概率求出來,然後二重迴圈累加每個格子的概率就是了。

如何求一個格子被染色的概率?要麼該矩陣在這個格子的左邊,要麼在上,下或者右邊,那麼如果以j值(列)來看,exp:如果最小j值和最大j值都在格子的左邊,是不是不用管i值,矩陣直接在格子左邊?依此類推,那麼j值矩陣不覆蓋的概率為p1=((j-1)*(j-1)+(n-j)*(n-j)/(n*n)

;依次類推出i值矩陣不覆蓋的概率p2,然後該格子被覆蓋的概率為 p=(1-p1)*(1-p2),再用1-p是沒有覆蓋該格子的概率,然後k次方就是k次都沒有覆蓋該格子的概率,用1-(1-p)^k就是一個格子被染色的概率。

為什麼不直接求該格子被染色的概率,而是直接1-減去p?假設該格子被覆蓋的概率為p那麼該格子被染色的概率就要用多項式來統計,非常麻煩...

程式碼如下:

#include<cstdio>
#include<algorithm>
using namespace std;
int m,n;
double pp(int i,int m)
{
double t1=i-1,t2=m-i;

return 1.0-(t1*t1+t2*t2)/(m*m);
}
double ans(int i,int j,int k)
{
   double x=1-pp(i,m)*pp(j,n),p=1;
   
   for(int i=1;i<=k;i++)
   p=p*x;
   
   return 1-p;
}
int main()
{
int i,j,k,t;

scanf("%d",&t);

for(int ll=1;ll<=t;ll++)
{

double res=0;
scanf("%d %d %d",&m,&n,&k);

for(i=1;i<=m;i++)
for(j=1;j<=n;j++)
{

res=res+ans(i,j,k);
}


    printf("Case #1: %.0lf\n",res);
    
}

return 0;
 }