Aeroplane chess(期望dp)

本文介绍了一个关于棋盘游戏的数学问题,利用动态规划方法解决从起点到终点掷骰子到达终点的期望次数,考虑了跳跃点的直接转移。通过递推公式dp[i] = (dp[i+1] + dp[i+2] + ... + dp[i+6])/6 + 1进行求解,并给出了C++代码实现。

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

LINK

题目

在这里插入图片描述

大致题意

有n个格点,掷骰子 ( 1 − − 6 ) (1--6) (16),超过n就胜利。现有m个跳跃点,到 x x x位置时可以直接飞到 y y y位置。问:从起点到终点掷骰子的期望次数。

思路

骰子每个面的概率为 1 / 6 1/6 1/6
d p [ i ] dp[i] dp[i]:从位置 i i i到达 n n n期望掷骰子的次数。所以 d p [ n ] = 0 dp[n]=0 dp[n]=0
当到达 x x x位置时可以直接飞到 y y y位置说明 d p [ x ] = d p [ y ] dp[x]=dp[y] dp[x]=dp[y]
求期望从后往前推
d p [ i ] = ( d p [ i + 1 ] + d p [ i + 2 ] + d p [ i + 3 ] + d p [ i + 4 ] + d p [ i + 5 ] + d p [ i + 6 ] ) / 6 + 1 dp[i]=(dp[i+1]+dp[i+2]+dp[i+3]+dp[i+4]+dp[i+5]+dp[i+6])/6+1 dp[i]=(dp[i+1]+dp[i+2]+dp[i+3]+dp[i+4]+dp[i+5]+dp[i+6])/6+1
加一操作:到达当前状态需要掷一次骰子。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
//#define int long long
const int N = 1e5+10;
vector<int>v[N];
int vis[N];
double dp[N];
signed main(){
//	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	int n,m,x,y;
	while(cin>>n>>m&&(m+n)){
		for(int i=1;i<=n;i++)v[i].clear();
		memset(dp,0,sizeof(dp));
		memset(vis,0,sizeof(vis));
		for(int i=0;i<m;i++){
			cin>>x>>y;
			v[y].push_back(x);
		}
		for(int i=n;i>=0;i--){
			if(i!=n&&!vis[i]){
				for(int j=1;j<7;j++){
					dp[i]+=dp[i+j]/6.0;
				}
				dp[i]+=1.0;
			}
			for(int j=0;j<v[i].size();j++){
				vis[v[i][j]]++;
				dp[v[i][j]]=dp[i];
			}
		}
		printf("%.4lf\n",dp[0]);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值