题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=5245
题意:
给出一个M*N的矩阵,从其中任意的选两个格子,将以两个格子为对角的矩形染色。这样的操作重复k次,问会被涂色的格子数的期望值。
分析:
期望值说白了就是执行完上述操作后,计算最有可能涂了多少个格子。
看了网上的题解才明白,我们只需要计算每一个格子可能被选中的概率,
期望值E(x)=x1*p1 + x2*p2 + ..... + xn*pn;
在这里我们把每1个格子看做独立事件,所以这里的x1=x2=.....=xn=1,
所以对于本题,期望值 E(x)=p1 + p2 + ..... + pn;
解题:
现在问题就简化成了求 每一个格子 被选中的概率,再累加即可。
先看一张图:(图片来自博客:点击打开链接)
假设现在我们求5这个点被涂色的概率,怎样可以让他染上色呢?
选点(x1,y1)和 (x2,y2)构成的矩形包含5这个点即可。
在矩阵中选两个点的总情况数 是 m*n * m*n
那么选点有9种情况:
1、若(x1,y1)在区域1,则(x2,y2)可以在区域5、6、8、9
2、若(x1,y1)在区域3,则(x2,y2)可以在区域4、5、7、8
3、若(x1,y1)在区域7,则(x2,y2)可以在区域2、3、5、6
4、若(x1,y1)在区域9,则(x2,y2)可以在区域1、2、4、5
5、若(x1,y1)在区域2,则(x2,y2)可以在区域4、5、6、7、8、9
6、若(x1,y1)在区域4,则(x2,y2)可以在区域2、3、5、6、8、9
7、若(x1,y1)在区域6,则(x2,y2)可以在区域1、2、4、5、7、8
8、若(x1,y1)在区域8,则(x2,y2)可以在区域1、2、3、4、5、6
9、若(x1,y1)在区域5,则(x2,y2)可以在任意区域
当前这个点被染色的概率就是这9种情况之概率和。
还有一个问题,k次染色。这样的话,可以这样,某个点被染色的概率算出来了
是p,那么该点不被染色的概率就是(1-p),
k次操作后仍然没被染色的概率就是(1-p)的k次方
所以k次操作后被染色的概率就是1-((1-p)的k次方)
注意尽量用double 数据类型,我之前用long long存m,n没过
详见代码:
#include
#include
#include
int main()
{
int T,k,t=1;
double m,n;
scanf("%d",&T);
while(T--)
{
scanf("%lf%lf%d",&m,&n,&k);
double sum=m*n*m*n; //所有情况
double ans=0;//期望值
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)//对每一个点算贡献值
{
double p1=0;//点i j被选中的方案数
//(x1,y1)在区域1.3.5.7
p1+=(i-1)*(j-1) * (m-i+1)*(n-j+1);
p1+=(i-1)*(n-j) * (m-i+1)*j;
p1+=(m-i)*(j-1) * i*(n-j+1);
p1+=(m-i)*(n-j) * i*j;
//(x1,y1)在区域2.4.6.8
p1+=(i-1)*1 * (m-i+1)*n;
p1+=1*(j-1) * m*(n-j+1);
p1+=1*(n-j) * m*j;
p1+=(m-i)*1 * i*n;
p1+=m*n; //(x1,y1)在区域5
double p=p1/sum;//点(i,j)选中的概率
ans+=1-pow(1-p,k);
}
printf("Case #%d: %.0lf\n",t++,ans);
}
return 0;
}