计蒜客oj 跳跃游戏
给定一个非负整数数组,假定你的初始位置为数组第一个下标。
数组中的每个元素代表你在那个位置能够跳跃的最大长度。
请确认你是否能够跳跃到数组的最后一个下标。
例如:
A = [2,3,1,1,4],
return true.
A = [3,2,1,0,4],
return false.
格式:
第一行输入一个正整数n,接下来的一行,输入数组A[n]。如果能跳到最后一个下标,输出“true”,否则输出“false”
样例1
输入:
5
2 0 2 0 1
输出:
true
分析:很明显的用dfs深度优先遍历可以解决这道题目,但是对于数据量500并且不知道数组每个位置元素的大小的情况下可能会超时 果不其然 超时了 仔细想来dfs会重复遍历如果剪枝不充分超时是必然的
法1:
#include<iostream>
#include<vector>
#include<algorithm>
#include<iterator>
using namespace std;
int arr[501];
bool flag=0;
int n;
void dfs(int na){//na为当前所处的下标位置
if(na>n){
return;
}
if(na==n){
flag=1;
return;
}
if(arr[na]==0){
return;
}
for(int i=arr[na];i>0;i--){
if(arr[na]+na>n);
else{
dfs(arr[na]+na);
}
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>arr[i];
}
dfs(1);
if(flag){
cout<<"true";
}
else{
cout<<"false";
}
return 0;
}
于是我们又想到了动态规划 完美解决
法2:
#include<iostream>
using namespace std;
int arr[501];
bool dp[501];//dp[i]表示从位置i开始是否能够到达末尾
int main(){
int n;
cin>>n;
dp[n]=1;
for(int i=1;i<=n;i++){
cin>>arr[i];
}
for(int i=n-1;i>0;i--){
bool flag=0;
for(int j=arr[i];j>0;j--){
if(dp[i+j]==1&&(i+j)<=n) flag=1;
}
if(flag){
dp[i]=1;
}
}
bool temp=dp[1];
if(temp){
cout<<"true";
}
else{
cout<<"false";
}
return 0;
}