hdu5245(概率)


题意大致是:进行K次染色,每次染色会随机选取一个以(x1,y1),(x2,y2)为一组对角的子矩阵进行染色,求K次染色后染色面积的期望值(四舍五入)。


显而易见的是,当K=1时,期望被染色的面积会等于每个1*1的方块被染色的期望累加之和。


假设K=1时即只染色一次时,位于第x行第y列的方块被染色的概率为A[x,y]

在K次操作后被染色的期望假设为P[x,y],可以用

P[x,y]=1-(1-A[x,y])^k
来计算。


所以就转为了求出A[x,y]。把所有的情况跑出来

由题目描述,一次染色中可能的操作有n^2*m^2种

计算A[x,y]时,我们可以把整个矩阵做如下拆分


当前计算的方块为[x,y],即图中编号为5的部分

将其他部分拆分成图上8个区域,则可得到以下关系

对于一种染色方案能够覆盖方块[x,y]时
①[x1,y1]取在区域1内时,[x2,y2]可以在5、6、8、9四个区域内任取;
②[x1,y1]取在区域2内时,[x2,y2]可以在4、5、6、7、8、9六个区域内任取;
③[x1,y1]取在区域3内时,[x2,y2]可以在4、5、7、8四个区域内任取;
④[x1,y1]取在区域4内时,[x2,y2]可以在2、3、5、6、8、9六个区域内任取;
⑤[x1,y1]取在区域5内时,[x2,y2]可以在所有区域内任取;
⑥[x1,y1]取在区域6内时,[x2,y2]可以在1、2、4、5、7、8六个区域内任取;
⑦[x1,y1]取在区域7内时,[x2,y2]可以在2、3、5、6四个区域内任取;
⑧[x1,y1]取在区域8内时,[x2,y2]可以在1、2、3、4、5、6六个区域内任取;
⑨[x1,y1]取在区域1内时,[x2,y2]可以在1、2、4、5四个区域内任取;
按照这个关系,即可推出A[x,y]的表达式。


P.S.:本题因为计算过程中会出现n^2*m^2大小的计算,因此需要注意int溢出的问题

参考:http://www.itkeyword.com/doc/7955111441277446327/hdu-5245-joyful



#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<ll,int> P;
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define clr(x,y) memset(x,y,sizeof x)
#define PI acos(-1.0)
#define ITER set<int>::iterator
const int Mod = 1e9 + 7;

const int maxn = 500 + 10;
double fun(double x,int k)
{
    double ret = 1.0;
    for(int i = 1;i <= k;i ++)ret *= x;
    return ret;
}
int main()
{
    int n,m,k;int Tcase;scanf("%d",&Tcase);
    for(int ii = 1;ii <= Tcase; ii ++)
    {
        scanf("%d%d%d",&n,&m,&k);
        double ans = 0;
        for(int i = 1;i <= n;i ++)
        {
            for(int j = 1;j <= m;j ++)
            {
                double p = 0;
                p += 1ll * (i - 1) * (j - 1) * (n - i + 1) * (m - j + 1);
                p += 1ll * (i - 1) * (n - i + 1) * m;
                p += 1ll * (i - 1) * (m - j) * (n - i + 1) * j;

                p += 1ll * (j - 1) * (m - j + 1)* n;
                p += 1ll * n * m;
                p += 1ll * (m - j) * (j ) * n;

                p += 1ll *(n - i) * (j - 1) * i * (m - j + 1);
                p += 1ll * (n - i) * i * m;
                p += 1ll * (n - i) * (m - j) * i * j;
//                cout << i << " " << j << " " << p << endl;
                p = p / n/n/m/m;
                ans += 1 - fun(1 - p,k);
            }
        }
        printf("Case #%d: %d\n",ii,(int)round(ans));
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值