HDU - 5245 Joyful (数学期望+求概率)

传送门:-->

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

For each test case, there is only one line, with three integers  M,N M,N and  K K
It is guaranteed that  1M,N500 1≤M,N≤500 1K20 1≤K≤20
Output
For each test case, output ''Case #t:'' to represent the  t 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.
题目大意:

  有一个n*m的矩阵有n*m个方格,然后有一个魔法棒可以用k次,每次可以随意在矩阵上确定两个点,然后以这两个点为对角线的子矩阵中的方格都会被染色。然后求档用完这k次后所被染色的方格数的期望是多少。

题解:

可以这样想一下,考虑每一方格的贡献率,也就是每个方格期望。先考虑用一次魔法棒的情况,在整个矩阵中要任意选两个点,选第一个点的时候有n*m种可能,选第二个点的时候也有 这么多种可能。总的选两个点也就是有n*n*m*m种可能。那么对于任意一个点(x,y)来说有多少种可能不被选到呢?可能选从第0列到y-1列的或者y+1到m列的或者第0到x-1行的或者选第x+1到n行的,这样才不会把(x,y)包含进去吧。那么可以统计一下这四种情况的可能情况数,可能数的计算和计算n*n*m*m一样,对于每个子矩阵都有选两个点的情况那就把这个子矩阵的大小面积乘一下就行了。那么这四种情况中会发现有重复计算的子矩阵,那就是四个角的重复计算的。既然重复计算了,那就减去就行了。当计算出在用一次魔法棒时(x,y)不会被染色的情况数的时候在除以总的情况就是该点的概率了,因为数就一个也就是点(x,y),所以期望就是概率p了,看好了这是(x,y)不被涂色的时候,那么k次都不被涂色的情况就是p^k,被涂色就是(1-p)了。然后充计每个点的期望就是总的期望了。


#include <iostream>
#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
int main()
{
    int t,n,m,k,w=0;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&m,&k);
        LL sum=(LL)n*n*m*m;///中间的运算不要用double丢精度
        double num=0.0;
        for(int x=1;x<=n;x++)
        {
            for(int y=1;y<=m;y++)
            {
                LL ans=0;///中间的运算不要用double 丢精度
                ans+=(LL)(x-1)*m*(x-1)*m;
                ans+=(LL)(n-x)*m*(n-x)*m;
                ans+=(LL)(y-1)*n*(y-1)*n;
                ans+=(LL)(m-y)*n*(m-y)*n;
                ans-=(LL)(x-1)*(y-1)*(x-1)*(y-1);
                ans-=(LL)(m-y)*(x-1)*(m-y)*(x-1);
                ans-=(LL)(y-1)*(n-x)*(y-1)*(n-x);
                ans-=(LL)(n-x)*(m-y)*(n-x)*(m-y);
                double ave=(double)ans*1.0/sum;
                double ant=1.0;
                for(int i=1;i<=k;i++)ant*=ave;
                //cout<<ans<<" "<<ave<<endl;
                num+=(1-ant);
            }
        }
        printf("Case #%d: %.0f\n",++w,num);
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值