计蒜客 跳跃游戏二 动态规划

本文介绍了一个寻找从数组起始位置到达末尾位置所需的最小跳跃次数的算法。通过动态规划的方法,实现了对每个位置进行遍历并计算到达该位置的最短路径。最终输出到达最后一个元素所需的最少跳跃次数。

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

            思路:只需要一直往右跳跃即可,没必要往左跳。dp(i)表示到达下标i的最小跳跃次数,递推其后的len[i]个点,dp(j) = min(dp(i)+1)

AC代码

#include <cstdio>
#include <cmath>
#include <cctype>
#include <bitset>
#include <algorithm>
#include <cstring>
#include <utility>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000") 
#define eps 1e-10
#define inf 0x3f3f3f3f
#define PI pair<int, int> 
typedef long long LL;
const int maxn = 100 + 5;
int a[maxn], dp[maxn];
int main() {
	int n;
	while(scanf("%d", &n) == 1) {
		for(int i = 0; i < n; ++i) {
			dp[i] = inf;
			scanf("%d", &a[i]);
		}
		dp[0] = 0;
		for(int i = 0; i < n-1; ++i) {
			int jump = a[i];
			for(int j = i+1; j <= i+jump && j < n; ++j) {
				dp[j] = min(dp[i] + 1, dp[j]);
			}
		}
		printf("%d\n", dp[n-1]);
	}
	return 0;
}

如有不当之处欢迎指出!

### 动态规划解决跳跃游戏问题 在跳跃游戏问题中,目标是判断从数组的第一个位置是否能够跳跃到数组的最后一个位置。使用动态规划(Dynamic Programming, DP)是一种直观且有效的方法。 #### 动态规划思路 动态规划的核心思想是:定义一个 `dp` 数组,其中 `dp[i]` 表示从起始位置跳跃到下标 `i` 的最大跳跃距离。如果 `dp[i]` 的值大于等于 `i`,说明可以从前面的位置跳跃到 `i`。最终目标是判断 `dp[n-1]` 是否大于等于 `n-1`(其中 `n` 是数组长度),即是否能够跳跃到数组的最后一个位置[^1]。 #### 解法代码示例 以下是一个使用动态规划实现的 C++ 示例代码: ```cpp class Solution { public: bool canJump(vector<int>& nums) { int n = nums.size(); vector<int> dp(n, 0); // dp[i] 表示到达下标 i 的最大跳跃距离 dp[0] = nums[0]; // 初始位置的最大跳跃距离 for (int i = 1; i < n; ++i) { dp[i] = max(dp[i - 1] - 1, nums[i]); // 每一步的最大跳跃距离 if (dp[i] == 0) return false; // 如果当前下标的跳跃距离为 0,则无法继续前进 } return true; // 能够到达数组的最后一个位置 } }; ``` #### 代码解析 - **初始化 `dp` 数组**: - `dp[0]` 初始化为 `nums[0]`,表示从起始位置可以跳跃的最大距离。 - **递推公式**: - 对于每个下标 `i`,算从 `i-1` 跳跃到 `i` 后的最大跳跃距离。`dp[i] = max(dp[i - 1] - 1, nums[i])`,其中 `dp[i - 1] - 1` 表示从前面位置跳跃到 `i` 后剩余的跳跃能力,`nums[i]` 是当前位置的跳跃能力。 - **判断跳跃能力**: - 如果某个下标 `i` 的跳跃距离为 `0`,则无法继续跳跃到下一个位置,直接返回 `false`。 - **返回结果**: - 如果能够遍历到数组的最后一个位置,返回 `true`,表示可以跳跃到终点。 #### 时间复杂度与空间复杂度 - **时间复杂度**:O(n),其中 `n` 是数组长度。需要遍历一次数组。 - **空间复杂度**:O(n),用于存储动态规划数组 `dp`。 #### 优化思路 可以进一步优化空间复杂度,将 `dp` 数组替换为一个变量 `max_reach`,用于记录当前能够跳跃到的最大下标。以下是优化后的代码: ```cpp class Solution { public: bool canJump(vector<int>& nums) { int max_reach = 0; // 当前能够跳跃到的最大下标 int n = nums.size(); for (int i = 0; i < n; ++i) { if (i > max_reach) return false; // 当前下标无法到达 max_reach = max(max_reach, i + nums[i]); // 更新最大跳跃距离 if (max_reach >= n - 1) return true; // 提前终止,已经可以到达终点 } return true; // 默认可以到达终点 } }; ``` #### 优化代码解析 - **`max_reach`**:记录当前能够跳跃到的最大下标。 - **提前终止**:如果 `max_reach` 已经大于等于数组的最后一个下标,则可以直接返回 `true`。 - **空间复杂度优化**:从 O(n) 降低到 O(1)。 #### 总结 通过动态规划的方法,可以有效地解决跳跃游戏问题。无论是使用 `dp` 数组还是优化后的 `max_reach` 变量,都能在 O(n) 的时间复杂度内完成判断。这种方法不仅直观,而且易于实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值