跳跃游戏(一,二)

来源:互联网 发布:中信国安历史交易数据 编辑:程序博客网 时间:2024/06/01 23:41

跳跃游戏二
题目:

给定一个非负整数数组,假定你的初始位置为数组第一个下标。

数组中的每个元素代表你在那个位置能够跳跃的最大长度。

你的目标是到达最后一个下标,并且使用最少的跳跃次数。

例如:

A=[2,3,1,1,4],到达最后一个下标的最少跳跃次数为2。(先跳跃111 步,从下标0 到1,然后跳3 步,到达最后一个下标。一共两次)

输入格式

第一行输入一个正整数 n(1≤n≤100)n,接下来的一行,输入n 个整数,表示数组 A

输出格式

最后输出最少的跳跃次数。

样例输入

53 1 1 1 1

样例输出

2代码:
import java.util.*;public class Main{public static void main(String args[])    {Scanner in =new Scanner(System.in);int num=in.nextInt();int []a=new int[num];int []dp=new int[num];//dp表示的是从起点跳到当前位置所需的次数for(int i=0;i<num;i++) {a[i]=in.nextInt();dp[i]=0;}for(int i=0;i<num;i++) {for(int j=1;j<=a[i];j++) {if(i+j<num) {if(dp[i+j]<=0) {dp[i+j]=dp[i]+1;}else if(dp[i]+1<dp[i+j]) {dp[i+j]=dp[i]+1;}}}}System.out.println(dp[num-1]);    }}
这个程序通过基本的测试用例也都是没问题,但是它还是存在这一些问题。。。。。
本来没有发现,其实这个程序是有错误的,当我们输入的数组中存在0的时候怎么办,这种情况没有考虑到。。。
例如当我们输入的数组为:{1,0,2,3,4}时,这时从第二个节点是不能在进行跳跃时,此时这个数组是无解的,这种情况也必须考虑到。
所以需要进行一下更正:
在第一个for循环中,i<num的判断条件,加一个与 dp[i]!=0;这就是说明,当它不能从第一个节点跳过去时,后面的节点就不需要进行判断了,
我们判断的节点,必须是可以从第一个节点跳过去的才可以。
但是当我们加入这个与的判定条件时,我们又会发现问题,因为我们默认的dp数组都是0,当我们加入这个判断条件时,我们会发现第一个节点,
就是不能通过for循环的,所以我们还需要做出一些改变。就是当判断第一个节点时,我们先修改dp的值,然后判断完之后,我们在改回来。。。
这个方法可能挺不好的,但是目前我还没有想到更好的解决办法,所以先这样进行訂正,以后想到更好的方法,在进行修改。
修改之后代码如下:
import java.util.*;public class Main{public static void main(String args[])    {Scanner in =new Scanner(System.in);int num=in.nextInt();int []a=new int[num];int []dp=new int[num];//dp表示的是从起点跳到当前位置所需的次数for(int i=0;i<num;i++) {a[i]=in.nextInt();dp[i]=0;}dp[0]=1;for(int i=0;i<num&&dp[i]!=0;i++) {dp[0]=0;for(int j=1;j<=a[i];j++) {if(i+j<num) {if(dp[i+j]<=0) {dp[i+j]=dp[i]+1;}else if(dp[i]+1<dp[i+j]) {dp[i+j]=dp[i]+1;}}}}if(dp[num-1]<=0)System.out.println("无解,跳不到最后一个节点 ");else System.out.println(dp[num-1]);    }}
跳跃游戏一:
其实也可以用这个方法来解,只需要将上面的输出做一个判断就好,如果dp[num-1]>0 则为true,否则为false。但是还有一点要注意,就是当只输入一个元素时,对跳跃游戏一来说可能有些问题,因为此时dp[0]=0,判断是false的,但是结果应该为true,所以这时只要修改一下dp[0]=0 的位置就好。但是事实上跳跃游戏有更好的解决方法:基于贪心算法的

问题:

给定一个非负整数数组,假定你的初始位置为数组第一个下标。

数组中的每个元素代表你在那个位置能够跳跃的最大长度。

请确认你是否能够跳跃到数组的最后一个下标。

例如:A=[2,3,1,1,4] 能够跳跃到最后一个下标,输出true

A=[3,2,1,0,4] 不能跳跃到最后一个下标,输出false

输入格式

第一行输入一个正整数 n(1≤n≤500)n(1 \leq n \leq 500)n(1n500),接下来的一行 nnn 个整数,输入数组 AiA_iAi

输出格式

如果能跳到最后一个下标,输出true,否则输出false

样例输入

52 0 2 0 1

样例输出

true
代码:
import java.util.Scanner;public class Main{      public static void main(String[] args) {          Scanner sc = new Scanner(System.in);          int n = sc.nextInt();          /*          * 思路:贪心算法;          * 从第一个数开始, 寻找可以一个可以跳最远的点;          * 例1:3 1 2 4 1 0 0          * 1.从第一个位置0,可以跳到位置1和位置2和位置3;          * 2.如果跳到位置1,那么最远就可以跳到位置(1+1);          * 3.如果跳到位置2,那么最远就可以跳到位置(2+2);          * 4.如果跳到位置3,那么最远就可以跳到位置(3+4);          * 5.故选择跳到位置3 ,重复1.2.3步;          *           * 算法分析:          * 1.如果选择跳到位置3 ,就无法跳到位置2和位置3, 那么会不会因此错过最优解? 答:不会!          * 2.因为任意位置1和位置2能到达的位置, 位置3都可以到达;          * 3.故不会错过最优解;          */          int[]a = new int[n];          for(int i= 0 ;i< n ;i++) {              a[i] = sc.nextInt();          }          int i;          int l;  //左边界       控制搜索的起始位置          int r;  //右边界       控制搜索的终止位置          for( i= 0 ;i< n && a[i]!= 0 ;) { //当a[i]==0 时 , 该位置为可到达的最远位置              r = i + a[i];              l = i + 1;               for(int j= i+1 ;j< n && j<= i+a[i] ;j++) {    //                  if(j+a[j] >= r){ //遍历可到达位置 能到达的最远位置                      r = j+ a[j];    //更新左右边界                      l = j;                  }              }              i = l;  //左边界                        }          if(i< n-1) {              System.out.println("false");                        }else{              System.out.println("true");          }      }  }

原创粉丝点击