Codeforce 1245 E. Hyakugoku and Ladders(期望dp,模拟)

在这里插入图片描述


题目大意:在一个 10 * 10 的网格图,终点在(1,1),起点在 (10,1),最底行的方向是向右,每一行的方向是下面一行的反方向,在一行的端点处方向是向上。除此之外每个位置可能还有梯子, a [ i ] [ j ] a[i][j] a[i][j] 表示第 i 行,第 j 列的梯子的长度为 a [ i ] [ j ] a[i][j] a[i][j],若 a [ i ] [ j ] = 0 a[i][j] = 0 a[i][j]=0,表示这个位置没有梯子。你有一个6个面的色子,每个面的权值分别为 1,2,3,4,5,6;每一轮你掷色子,然后沿着当前方向走 p 步,p是你掷色子掷出来的值,如果你走的步数超过你到终点的步数,那么你会停止不动,但仍然算一轮,如果你要上梯子,你必须先走到梯子下面,且上梯子时不能换其它梯子,只能上当前这个位置的梯子,也可以选择不上,问期望多少轮你可以走到终点。

简单期望DP,从终点倒过来逆推,若某个点有梯子,则取走梯子和不走梯子的最小值进行转移即可。


代码:

#include<bits/stdc++.h>
using namespace std;
const double ep = 1.0 / 6; 
typedef long long ll;
int a[12][12];
double dp[12][12];
int main() {
	for(int i = 1; i <= 10; i++)
		for(int j = 1; j <= 10; j++)
			scanf("%d",&a[i][j]);
	dp[1][1] = 0;
	for(int i = 1; i <= 10; i++) {
		if(i & 1) {
			for(int j = 1; j <= 10; j++) {
				double tmp = 1,fm = 1;
				if(i == 1 && j == 1) continue;
				for(int k = 1; k <= 6; k++) {
					if(j - k >= 1) {
						int p = a[i][j - k];
						tmp += min(dp[i][j - k],dp[i - p][j - k]) * ep;
					} else {
						if(i > 1) {
							tmp += ep * min(dp[i - 1][k - j + 1],dp[i - 1 - a[i - 1][k - j + 1]][k - j + 1]);
						} else {
							fm -= ep;
						}
					}
				}
				dp[i][j] = tmp / fm;
			}
		} else {
			for(int j = 10; j >= 1; j--) {
				double tmp = 1,fm = 1;
				for(int k = 1; k <= 6; k++) {
					if(j + k <= 10) {
						tmp += min(dp[i][j + k],dp[i - a[i][j + k]][j + k]) * ep;
					} else {
						tmp += ep * min(dp[i - 1][20 - k - j + 1],dp[i - 1 - a[i - 1][20 - k - j + 1]][20 - k - j + 1]);
					}
				}
				dp[i][j] = tmp / fm;
			}
		}
	}
	printf("%.10lf\n",dp[10][1]);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值