HDU 5245 Joyful(概率题求期望)

D - Joyful
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u
Submit Status

Description

Sakura has a very magical tool to paint walls. One day, kAc asked Sakura to paint a wall that looks like an $M \times N$ matrix. The wall has $M \times N$ squares in all. In the whole problem we denotes $(x, y)$ to be the square at the $x$-th row, $y$-th column. Once Sakura has determined two squares $(x_1, y_1)$ and $(x_2, y_2)$, 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 $K$ times. More specifically, each time for Sakura to use that tool, she just randomly picks two squares from all the $M \times N$ 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 $T$($T \le 100$), denoting the number of test cases. 

For each test case, there is only one line, with three integers $M, N$ and $K$. 
It is guaranteed that $1 \le M, N \le 500$, $1 \le K \le 20$. 
 

Output

For each test case, output ''Case #t:'' to represent the $t$-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

Hint The precise answer in the first test case is about 3.56790123. 

题意:有t组数据,每组输入m,n,k。表示有一个m*n的矩阵,在矩阵中随机取两个点(x1,y1),(x2,y2),以这两个点为矩形的两个顶点,画一个矩形,即矩形的四个顶点为(x1,y1),(x1,y2),(x2,y1),(x2,y2)。矩形中的所有点视为被染色,进行k次这样的操作,问该矩阵中被染色的格子的个数的期望。这两个点互不影响,也就是这两个点可以相同。每个点可以被多次染色,就是被染两次就算两次,不是算一次。

题解:因为(x1,y1),(x2,y2)这两个点是从矩阵中取的,第一个点有n*m种可能性,第二个点也有n*m种可能性,所以总的情况数为n*n*m*m。我们对矩阵中的每个点进行单独讨论,假设有这么一个点x,y。我们知道,x表示该点在第x行,y表示该点在第y列,那么如果取的那两个点(x1,y1),(x2,y2)都在1到x-1行或者都在x+1到m行之间或者都在1到y-1列之间或者都在y+1到n列之间,则(x,y)这个点不会被染色,将上面的四种情况可以看做是上下左右四种情况。根据容斥原理,我们要减去左上,左下,右上,右下这四种情况,这是因为上和左同时覆盖左上,以此类推。用该情况数除以总情况数所得概率p就是该点不被染色的概率,进行k次该操作,则tmp=p^k就是该点k次操作之后不被染色的概率,1-tmp就是该点被染色的概率,因为该点是一个点,所以概率就是期望,将每个点的期望加起来,就是结果了,注意四舍五入用%.0f就能实现,具体的有很多很多需要注意的细节问题请看代码注释。

#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;
typedef long long ll;
ll c(ll a,ll b)
{
    return a*a*b*b;
}
int main()
{
    /*1.用G++提交 C++慢 有可能都超时
    2.用scanf写 cin慢 虽然在本题中一样
    3.tmp用循环跑 pow慢*/
    int t,cas=1;
    scanf("%d",&t);
    while(t--)
    {
        ll n,m,k;//这里nm顺序无所谓
        //注意这里一定要用long long,要不然计算的时候还得强制转化一下
        scanf("%lld%lld%lld",&n,&m,&k);
        ll ans,sum=n*n*m*m;
        //ans除以sum求不被染色概率
        //两个格子每个都有n*m种选择
        double p,qiwang=0;
        //p表示该格子一次操作后不被染色的概率
        //qiwang表示该格子被染色的概率也就是期望,因为是相对于一个格子而言的 乘数为1
        for(int i=1;i<=n;i++)//对每个格子进行讨论
            for(int j=1;j<=m;j++)
        {
            ans=0;//初始化
            //容斥原理
            ans+=c(i-1,m);
            ans+=c(n-i,m);
            ans+=c(n,j-1);
            ans+=c(n,m-j);
            ans-=c(i-1,j-1);
            ans-=c(i-1,m-j);
            ans-=c(n-i,j-1);
            ans-=c(n-i,m-j);
            p=1.0*ans/sum;//该格子不被染色的概率
            double tmp=1;//初始化
            //该格子k次操作后不被染色的概率
            for(int i=0;i<k;i++)//pow返回double 不要用pow
                tmp*=p;
            //该格子被染色的概率也就是期望
            qiwang+=1-tmp;
        }
        // %0.f自动取整了 或者floor+0.5或者round函数也可以
        printf("Case #%d: %.0lf\n",cas++,qiwang);
    }
    return 0;
}

这个题之前把题目里的题号写错了,写成5345了。(流汗)

posted @ 2016-04-30 23:31  Ritchie丶  阅读(561)  评论(0编辑  收藏  举报