0
点赞
收藏
分享

微信扫一扫

[动态规划]DP26 跳跃游戏(一)-简单

​​DP26 跳跃游戏(一)​​

描述

给定一个非负整数数组nums,假定最开始处于下标为0的位置,数组里面的每个元素代表下一跳能够跳跃的最大长度。如果能够跳到数组最后一个位置,则输出true,否则输出false。

数据范围:

输入描述:

第一行输入一个正整数 n ,表示数组 nums 的长度

第二行输入 n 个整数表示数组的每个元素

输出描述:

输出 true 或者 false

示例1

输入:

7
2 1 3 3 0 0 100

输出:

true

说明:

首先位于nums[0]=2,然后可以跳2步,到nums[2]=3的位置,再跳到nums[3]=3的位置,再直接跳到nums[6]=100,可以跳到最后,输出true

示例2

输入:

7
2 1 3 2 0 0 100

输出:

false

说明:

无论怎么样,都跳不到nums[6]=100的位置

题解

动态规划解法

根据题意,只要我们可以从任意的一个台阶调到最后一个台阶就输出true。实际上就是求到达任意索引i的时候,可以跳跃到的最大台阶的索引。动态规划步骤如下:

  1. dp[i]表示从前面的[0,i]中的台阶可以跳到的最大索引值
  2. 初始化:dp[0]=v[0]
  3. 递推关系:dp[i]=max(dp[i-1],i+v[i]),表示从[0,i-1]的台阶可以的高度和当前台阶可以跳的高度中选取一个最大值

注意:

  1. 对于任意的索引i,如果dp[i-1] < i,表示不可以从[0,i-1]的台阶跳到索引为i的台阶,此时直接返回false
  2. 对于任意的索引,如果dp[i] >= v.size() - 1,表示从此台阶就可以跳到最后一个台阶,此时直接返回true


代码如下:

#include <bits/stdc++.h>

bool solve(const std::vector<int> &v)
{
if (v.size() <= 1)
{
return true;
}

// dp[i]表示从i点可以跳跃到的最大索引
std::vector<int> dp(v.size(), 0);
dp[0] = v[0];
for (int i = 1; i < v.size(); ++i)
{
if (dp[i - 1] < i)
{
return false;
}
dp[i] = std::max(dp[i - 1], i + v[i]);
if (dp[i] >= v.size() - 1)
{
return true;
}
}
return true;
}

int main()
{
int n;
std::cin >> n;
std::vector<int> v(n);
for (int i = 0; i < n; ++i)
{
std::cin >> v[i];
}

std::cout << (solve(v) ? "true" : "false") << std::endl;
return 0;
}

贪心解法

根据动态规划解法的分析,实际上我们可以使用贪心解法来解决这个问题,不必引入dp数组(实际上,贪心解法也是动态规划的一种~)。


bool solve_2(const std::vector<int> &v)
{
if (v.size() <= 1)
{
return true;
}

std::vector<int> dp(v.size(), 0);
int max_hight = v[0];// 表示当前可以跳到的最大高度
for (int i = 1; i < v.size(); ++i)
{
if (max_hight < i)
{
return false;
}
max_hight = std::max(max_hight, i + v[i]);
if (max_hight >= v.size() - 1)
{
return true;
}
}
return true;
}


举报

相关推荐

0 条评论