题目描述
小明和朋友们一起玩跳格子游戏,每个格子上有特定的分数 score = [1, -1, -6, 7, -17, 7]
。从起点 score[0]
开始,每次最大的步长为 k
,请你返回小明跳到终点 score[n-1]
时,能得到的最大得分。
输入描述
- 第一行输入一个整数
n
,表示格子的数量。 - 第二行输入
n
个整数,表示每个格子的分数score[i]
。 - 第三行输入一个整数
k
,表示最大跳的步长。
输出描述
- 输出最大得分。
用例输入
6
1 -1 -6 7 -17 7
2
14
解题思路
本题可以通过动态规划来解决。设 dp[i]
表示到达格子 i
时能得到的最大得分。根据题意,我们需要从起点 score[0]
出发,每次跳跃的步长最多为 k
,因此可以通过以下方式进行状态转移:
-
状态定义:
dp[i]
表示到达格子i
时的最大得分。
-
状态转移:
- 从格子
i
可以跳到i+1, i+2, ..., i+k
中的任意一个,因此需要更新每个目标格子的得分。 - 对于每个格子
i
,我们更新到达i+j
的最大得分,公式为:
dp[i + j] = max(dp[i + j], dp[i] + score[i + j])
,其中j
代表从i
跳到i+j
。
- 从格子
-
初始化:
dp[0] = score[0]
,即起点的得分就是score[0]
。
-
最终结果:
- 我们关心的是
dp[n-1]
,即到达终点时的最大得分。
- 我们关心的是
代码
#include <iostream>
#include <vector>
#include <map>
#include <climits>
#include <algorithm>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, k;
cin >> n; // 格子的数量
vector<int> score(n);
for (int i = 0; i < n; i++) {
cin >> score[i]; // 每个格子的分数
}
cin >> k; // 最大步长
// dp[i] 表示到达格子 i 时的最大得分
vector<int> dp(n, INT_MIN); // 初始化为最小值,表示还没有到达该格子
dp[0] = score[0]; // 起点的得分就是第一个格子的分数
for (int i = 0; i < n; i++) {
if (dp[i] == INT_MIN) continue; // 如果当前格子不可达,则跳过
// 从格子 i 跳跃到后续格子
for (int j = 1; j <= k && i + j < n; j++) {
dp[i + j] = max(dp[i + j], dp[i] + score[i + j]);
}
}
cout << dp[n - 1] << endl;
}