【算法题】网易校招2020秋笔试题第4题:跳柱子

跳柱子

【题目描述】

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

【输入描述】

第一行数据组数T
对于每组数据,第一行数字n,k接下来一行n个数字表示hi。
1≤n≤1000,1≤hi≤10^9,1≤T≤10,1≤k≤n

【输出描述】

对于每组数据,输出YES或NO

【示例】

示例1:
输入:

1
5 3
6 2 4 3 8

输出:

YES

示例2:
输入:

1
5 2
1 8 2 3 4

输出:

NO

【解题代码】

方案1:没有测试过

public class Solution {
    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[] h = new int[n];
            for (int i = 0; i < n; i++) {
                h[i] = sc.nextInt();
            }
            if (solve(h, k)) {
                System.out.println("YES");
            } else {
                System.out.println("NO");
            }
        }
    }

    public static boolean solve(int[] h, int k) {
        boolean superPower = true;
        //找k以内最高的
        //找k以后比
        for (int i = 0; i < h.length; ) {
            int skip= -1;
            int superMax = i;
            for (int j = i + 1; j <= i + k && j<h.length; j++) {
                //h[j] 更小
                if (h[j] <= h[i]) {
                    if(j == h.length-1){
                        return true;
                    }
                    if (skip == -1 || h[skip] <= h[j]) {
                        skip = j;
                    }
                } else { //h[j]更大
                     if(h[superMax] <= h[j]){
                         superMax = j;
                     }
                }
            }
            if(skip == -1 && superPower){ //没用超能力
                skip = superMax; //用超能力
                superPower = false;
            }else if(skip == -1 && !superPower){
                return false;
            }
            i = skip;
            if(i == h.length-1){
                break;
            }
        }
        return true;
    }
}

方案2:动态规划

public class Solution {
    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[] h = new int[n];
            for (int i = 0; i < n; i++) {
                h[i] = sc.nextInt();
            }
            if (solve(h, k)) {
                System.out.println("YES");
            } else {
                System.out.println("NO");
            }
        }
    }

    public static boolean solve(int[] h, int k) {
        for (int i = 1; i < dp.length; i++) {
            // 不用超能力到达j
            for (int j = i - 1; j >= i - k && j >= 0; j--) {
                if (dp[j] == 1 && h[j] >= h[i]) { //前面不用超能力到达j,不用超能力,能从j到达i
                    dp[i] = 1;
                    break;
                }
            }
            if (dp[i] == 1) continue;
            for (int j = i - 1; j >= i - k && j >= 0; j--) {
                if (s > 0 && dp[j] == 1 && h[j] < h[i]) {
                    dp[i] = 2;
                    break;
                }
                else if (dp[j] == 2 && h[j] >= h[i]) { //用超能力达到j,再直接从j到达i
                    dp[i] = 2;
                    break;
                }
            }
            if (dp[i] == -1) dp[i] = 0; //不能直接到达 且 不能使用超能力到达,则该点就不可到达
        }
        return (dp[dp.length - 1] == 1 || dp[dp.length - 1] == 2);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值