【网易笔试题】小易跳柱子

题目:
小易有n根柱子,第i根柱子的高度为hi。一开始小易站在第一根柱子上。小易能从第i根柱子跳到第j根柱子,当且仅当hj<=hi且k其中为指定的一个数字。
另外小易拥有一次释放超能力的机会。这个超能力能让小易从柱子i跳到任意满足小于等于k的柱子而无视柱子高度的限制。
现在小易想知道,小易是否能到达第n根柱子。

输入描述:
第一行数据组数
对于每组数据,第一行数字,接下来一行个数字表示.
输入例子1:
1
5 3
6 2 4 3 8
输出例子1:
YES

思路:
参考自 AFUWUS,稍作修改 。

核心思想在于动态规划,二维数组。
 当前一节点正常跳跃是成功的,该节点无法正常跳跃,则该节点的超能路线置为成功。
 当前一节点的超能跳跃成功情况下,该节点的超能路线就只能通过正常跳跃实现成功了。
 这就避免了多次超能跳跃情况的发生
 最后节点只要正常或超能跳跃成功就算成功。

代码:

import java.util.Scanner;
import java.util.*;
import java.lang.String;
public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int T=sc.nextInt();
        while(T-->0){
            int n=sc.nextInt();
            int k=sc.nextInt();
            int[] height=new int[n];
            for(int i=0;i<n;i++){
                height[i]=sc.nextInt();
            }
            if(solve(height,k)){
                System.out.println("YES");
            }else{
                System.out.println("NO");
            }
        }
    }
    public static boolean solve(int[] height,int k){
        int n=height.length;
        boolean[][] dp=new boolean[n][2];
        //初始条件
        dp[0][0]=dp[0][1]=true;
        for(int i=0;i<n;i++){
            for(int j=i-1;j>=0 && j>=i-k;j--){
                //如果第j根柱子不使用超能力能达到
                if(dp[j][0]){
                    
                    //如果距离和高度都满足条件,那么第i根柱子在不使用超能力的情况下也是可以达到的
                    if(height[j]>=height[i]){
                        dp[i][0]=true;
                    }else{
                        dp[i][1]= true;
                    }
                }
                //如果第j根柱子使用超能力能达到
                if(dp[j][1]){
                    //那么如果满足条件下,第i根柱子在已经使用了超能力的情况下,能够达到
                    if(height[j]>=height[i]){
                        dp[i][1]=true;
                    }
                }
            }
        }
        //最终的答案是,在允许使用超能力的情况下,能否到达最后一根柱子
        return dp[n-1][1];
    }

}	

你可能感兴趣的:(算法题)