BUAA 540 概率dp

本文介绍了一道关于多米诺骨牌的概率问题,玩家需要依次检查并触碰未倒下的骨牌,骨牌触碰后会以一定概率向相邻的方向倒下。文章提供了求解触碰骨牌总次数期望值的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

多米诺骨牌

时间限制: 2000 ms 内存限制: 131072 kb

题目描述

constroy 喜欢玩多米诺骨牌,他把若干块骨牌排列成一个 nn 行 mm 列的矩阵准备进行游戏。

但是 constroy 太笨了,他无法用一次触碰使所有的骨牌全部倒下。于是,他从第一行第一列的骨牌开始检查,依次检查第一行第二列,第一行第三列,……,第二行第一列,第二行第二列,……,第 nn 行第 mm 列的骨牌。如果他检查到一块骨牌没有倒下,那么他就会触碰它。而第 ii 行第 jj 列立着的骨牌被触碰时,有 pi,jpi,j 的概率向下一行倒,有 qi,jqi,j 的概率向下一列倒,并触碰该方向上与其相邻的骨牌(如果存在)。

请你估计一下笨拙的 constroy 总共触碰骨牌次数的期望值是多少吧。

提示:期望值是试验中每次可能结果的概率乘以其结果的总和。

输入

第一行包含一个正整数 TT ,表示有 TT 组测试数据。

接下来依次给出每组测试数据。对于每组测试数据:

第一行包含两个正整数 nn 和 mm 。

接下来 nn 行,每行包含 mm 个非负实数,其中第 ii 行第 jj 个数代表对应位置骨牌向下一行倒的概率 pi,jpi,j 。

接下来 nn 行,每行包含 mm 个非负实数,其中第 ii 行第 jj 个数代表对应位置骨牌向下一列倒的概率 qi,jqi,j 。

保证所有输入的实数满足小数点后数字不超过两位。

保证在一行中的每个实数之间有恰好一个空格,没有其他额外的空格。

1T25,1n,m5001≤T≤25,1≤n,m≤5000pi,j+qi,j10≤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;
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值