(概率dp/期望)Aeroplane chess

本文探讨了一种飞行棋游戏的数学模型,棋盘由N+1格组成,玩家从0格开始,通过掷骰子移动。文章考虑了额外的M条航线,允许玩家在特定格子间瞬移,目标是计算到达N格所需的平均掷骰子次数。通过动态规划方法,文章详细解释了如何计算这一期望值。

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

Hzz loves aeroplane chess very much. The chess map contains N+1 grids labeled from 0 to N. Hzz starts at grid 0. For each step he throws a dice(a dice have six faces with equal probability to face up and the numbers on the faces are 1,2,3,4,5,6). When Hzz is at grid i and the dice number is x, he will moves to grid i+x. Hzz finishes the game when i+x is equal to or greater than N.
There are also M flight lines on the chess map. The i-th flight line can help Hzz fly from grid Xi to Yi (0<Xi<Yi<=N) without throwing the dice. If there is another flight line from Yi, Hzz can take the flight line continuously. It is granted that there is no two or more flight lines start from the same grid.
Please help Hzz calculate the expected dice throwing times to finish the game.

题意即为飞行棋,0-n共n+1格,m条航线可以从xi-yi,没有航线的话可以扔骰子后移动到当前位置+骰子点数的位置,当位置>=n时结束,求扔骰子的次数期望
如果该地有航线dp[i]=dp[y[i]]直接继承期望,否则dp[i]=1/6*dp[i+1]+1/6*dp[i+2]+…+1/6*dp[i+6]+1;

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 5;
double dp[maxn];
int air[maxn];
int main()
{
    int n, m, x, y;
    while(~scanf("%d%d", &n, &m)) {
        if(n == m && n == 0) break;
        memset(air, 0, sizeof(air));
        dp[n] = 0.0;
        for(int i = 1; i <= m; i++) {
            scanf("%d%d", &x, &y);
            air[x] = min(n, y);
        }
        for(int i = n - 1; i >= 0; i--) {
            if(air[i] > 0) dp[i] = dp[air[i]];
            else {
                dp[i] = 1.0;
                for(int j = 1; j <= 6; j++)
                    dp[i] += 1.0 / 6 * dp[(i + j > n) ? n : i + j];
            }
        }
        printf("%.4f\n", dp[0]);
    }
}

目前尚未找到有关2024年福建师范大学(FJNU)程序设计竞赛中涉及飞行棋的具体问题陈述或解决方案。然而,可以基于以往的比赛题目和常见的算法竞赛模式推测可能的设计方向。 以下是关于飞行棋类问题的一般分析框架: ### 飞行棋问题的核心要素 1. **游戏规则建模** 飞行棋通常涉及多个玩家轮流掷骰子并移动棋子。需要定义棋盘结构、起点终点位置以及特殊格子的行为逻辑(如跳跃、退步或其他惩罚/奖励机制)。这可以通过图论中的有向加权图来实现[^1]。 2. **状态转移方程** 使用动态规划或者广度优先搜索(BFS)解决最短路径问题。假设当前状态下某枚棋子位于第`i`个格子,则下一步的状态取决于骰子的结果范围(通常是1到6),从而形成一系列新的候选状态集合[^2]。 3. **优化策略** 如果存在多枚棋子同时参与比赛的情况,则需考虑冲突检测与规避方法;另外还需兼顾时间复杂度的要求,在大规模数据集下采用记忆化搜索技术减少重复计算开销[^3]。 ```cpp #include <bits/stdc++.h> using namespace std; const int MAXN = 1e5 + 5; int dp[MAXN]; // 记录到达每个位置所需的最小步数 void solve(){ memset(dp, -1, sizeof(dp)); queue<int> q; q.push(0); // 假设起始点为索引0处 dp[0] = 0; while(!q.empty()){ int u = q.front(); q.pop(); for(int step=1;step<=6 && u+step<MAXN; ++step){ int v = u + step; if(v >= N || dp[v]!=-1) continue; // 越界检查&已访问节点跳过 // 特殊事件处理 如传送门等 if(specialEventExists(v)){ v = getDestinationFromSpecialEvent(v); } dp[v] = dp[u]+1; q.push(v); } } cout << (dp[N-1]==-1 ? "Impossible" : to_string(dp[N-1])) << endl; } ``` #### 注意事项 上述代码仅为伪代码示意如何利用队列配合数组完成基本的飞行棋模拟过程,并未完全贴合实际赛题需求,请根据具体条件调整细节部分。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值