2023年GESP六级考题解析:闯关游戏的最优路径选择
一、问题背景
题目模拟一个闯关游戏,玩家位于第0关,每次可以选择M种前进方式中的一种(前进a[i]关),每通过一关可以获得b[i]分数。需要计算从第0关出发到通关(第N关)的最大得分。
二、算法核心思想
三、完整代码解析(带详细注释)
#include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { ios::sync_with_stdio(false); // 关闭同步流加速输入输出 cin.tie(nullptr); // 解除cin和cout的绑定 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]; // DP数组初始化,dp[i]表示从第i关到终点的最大得分 vector<int> dp(N + 1, -1e9); // 初始化为极小值表示不可达 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; // 输出从第0关出发的最大得分 return 0; }
四、关键知识点详解
五、实际应用场景
六、学习建议
对比正向和逆向DP的实现差异
尝试修改为记录具体路径的版本
思考如何处理负分关卡的情况
练习类似的动态规划变种问题
参考:GESP六级题闯关游戏
原创内容 转载请注明出处