多米诺骨牌
题目描述
constroy
喜欢玩多米诺骨牌,他把若干块骨牌排列成一个
n
n 行
m
m 列的矩阵准备进行游戏。
但是 constroy
太笨了,他无法用一次触碰使所有的骨牌全部倒下。于是,他从第一行第一列的骨牌开始检查,依次检查第一行第二列,第一行第三列,……,第二行第一列,第二行第二列,……,第
n
n 行第
m
m 列的骨牌。如果他检查到一块骨牌没有倒下,那么他就会触碰它。而第
i
i 行第
j
j 列立着的骨牌被触碰时,有
pi,j
pi,j 的概率向下一行倒,有
qi,j
qi,j 的概率向下一列倒,并触碰该方向上与其相邻的骨牌(如果存在)。
请你估计一下笨拙的 constroy
总共触碰骨牌次数的期望值是多少吧。
提示:期望值是试验中每次可能结果的概率乘以其结果的总和。
输入
第一行包含一个正整数 T T ,表示有 T T 组测试数据。
接下来依次给出每组测试数据。对于每组测试数据:
第一行包含两个正整数 n n 和 m m 。
接下来 n n 行,每行包含 m m 个非负实数,其中第 i i 行第 j j 个数代表对应位置骨牌向下一行倒的概率 pi,j pi,j 。
接下来 n n 行,每行包含 m m 个非负实数,其中第 i i 行第 j j 个数代表对应位置骨牌向下一列倒的概率 qi,j qi,j 。
保证所有输入的实数满足小数点后数字不超过两位。
保证在一行中的每个实数之间有恰好一个空格,没有其他额外的空格。
1≤T≤25,1≤n,m≤500 1≤T≤25,1≤n,m≤500, 0≤pi,j+qi,j≤1 0≤pi,j+qi,j≤1
输出
对于每组数据输出一行,包含一个实数,表示 constroy
总共触碰次数的期望。
对于本题,输出的实数需要精确到小数点后恰好四位。
输入样例
1
2 2
0.5 0.5
0.5 0.5
0.5 0.5
0.5 0.5
输出样例
2.2500
题解:由于概率是线性叠加的 当前位置需要推一下的期望是(1-上边向下倒的概率乘上)*(1-左边往右倒的概率) 然后叠加起来
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
double down[505][505],rig[505][505],now[505][505];
int main(){
int t,n,m,i,j;
scanf("%d",&t);
while(t--){
memset(now,0,sizeof(now));
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
for(j=1;j<=m;j++)scanf("%lf",&down[i][j]);
}
for(i=1;i<=n;i++){
for(j=1;j<=m;j++)scanf("%lf",&rig[i][j]);
}
double ans=1;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
if(i==j&&i==1)continue;
ans+=((1-down[i-1][j])*(1-rig[i][j-1]));
}
}
printf("%.4f\n",ans);
}
return 0;
}