当前位置:首页 > GESP > GESP六级题解:洛谷P10108闯关游戏动态规划解法详解

GESP六级题解:洛谷P10108闯关游戏动态规划解法详解

18小时前

GESP六级题解:洛谷P10108闯关游戏动态规划解法详解 GESP六级题解 动态规划解法 洛谷P10108 C++代码示例 算法优化技巧 第1张

一、题目解读

本文针对2023年GESP六级题目“闯关游戏”(洛谷P10108)进行详细解析。题目要求玩家通过不同关卡路径选择,计算从起点到终点的最大得分。关卡间存在跳跃规则,需结合动态规划思想设计高效算法,最终输出最优得分。

二、解题思路

采用动态规划(Dynamic Programming)策略。核心思路为:

1. 逆向求解:从终点反向推算每关的最大得分,避免路径重复计算。

2. 状态定义:dp[i]表示从第i关到终点的最大得分,边界条件dp[N]=0(终点得分为0)。

3. 状态转移:遍历每关可选跳跃步数a[i],计算下一关得分dp[next] + 当前关得分b[i],取最大值更新dp[x]。

三、解题步骤拆解

1. 输入与初始化:读入关卡数N、跳跃规则数M,存储跳跃步数a[]与关卡得分b[]。

2. 动态规划核心逻辑:

从N-1关开始逆向循环,避免依赖后续状态。

遍历每个跳跃规则,计算可达下一关索引next。

若next关得分已计算(dp[next]有效),更新当前dp[x]为max(dp[next] + b[x])。

3. 输出结果:最终dp[0]即为起点到终点的最大得分。

四、代码与注释

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    ios::sync_with_stdio(false); // 加速输入输出
    cin.tie(nullptr);
    
    int N, M; // N:关卡数,M:跳跃规则数
    cin >> N >> M;
    vector<int> a(M), b(N); // a[]存储跳跃步数,b[]存储关卡得分
    for (int i = 0; i < M; ++i) cin >> a[i];
    for (int i = 0; i < N; ++i) cin >> b[i];
    
    vector<int> dp(N + 1, -1e9); // dp[i]:从第i关到终点的最大得分
    dp[N] = 0; // 终点得分初始化为0
    
    // 逆向动态规划
    for (int x = N - 1; x >= 0; --x) {
        int max_score = -1e9; // 临时存储当前关最大得分
        for (int i = 0; i < M; ++i) {
            int next = min(x + a[i], N); // 计算跳跃后可达的下一关(不越界)
            if (dp[next]!= -1e9) { // 若下一关得分已计算
                max_score = max(max_score, dp[next] + b[x]); // 更新当前得分
            }
        }
        dp[x] = max_score; // 更新状态
    }
    
    cout << dp[0] << endl; // 输出起点到终点的最大得分
    return 0;
}

五、总结

本文通过动态规划解法,高效解决了GESP六级“闯关游戏”题目。逆向计算与状态压缩避免了重复计算,适用于存在路径依赖关系的优化问题。掌握此类算法思维,可提升对复杂路径规划类题目的解题能力。




原创内容 转载请注明出处

分享给朋友:

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。