HDU 5245 Joyful(概率题求期望)
Description
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
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
Sample Input
Sample Output
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了。(流汗)