1. 程式人生 > >計蒜客oj 跳躍遊戲 動態規劃 dfs

計蒜客oj 跳躍遊戲 動態規劃 dfs

計蒜客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;
} 

這裡寫圖片描述