蓝桥杯 算法提高 秘密行动(Java)

问题描述
  小D接到一项任务,要求他爬到一座n层大厦的顶端与神秘人物会面。这座大厦有一个神奇的特点,每层的高度都不一样,同时,小D也拥有一项特殊能力,可以一次向上跳跃一层或两层,但是这项能力无法连续使用。已知向上1高度消耗的时间为1,跳跃不消耗时间。由于事态紧急,小D想知道他最少需要多少时间到达顶层。
输入格式
  第一行包含一个整数n,代表楼的高度。

  接下来n行每行一个整数ai,代表i层的楼层高度(ai <= 100)。
输出格式
  输出1行,包含一个整数,表示所需的最短时间。
样例输入
5
3
5
1
8
4
样例输出
1
数据规模和约定
  对20%的数据,n<=10
  对40%的数据,n<=100
  对60%的数据,n<=5000
  对100%的数据,n<=10000

思路:

  1. 本道题目涉及到动态规划,也就是说我们要如何正确的选择跳和爬才能使得花费的时间最小,我们知道跳跃完成后需要休息不能连续使用,而我们希望当跳跃完成后下一层楼的高度是1,或者是比前一层还要来得小的。就本例题进行分析:首先我们可以将第一层的高度作为需要爬一层楼的高度(也就是需要消耗的时间),从第二层开始进行循环,然后和当前跳的层数花费的时间进行比较,我们知道跳的层数是不需要花费时间的而跳跃这个数组实际上存储的是前两次爬的花费时间的最优解,代入状态转移方程:

P[i] = min(T[i - 1], P[i - 1]) + arr[i]
  1. 我们就可以更新我们爬楼所用的时间了,紧接着我们在比较前两次爬楼的时间所花费的时间,小的就说明我们是跳到前面这层,而下一层不能跳了需要爬,而花费的时间就等于小的这个值。拿本题来举例,最后一次循环时,我们可以选跳到花费9个时间点的楼层的前面,也可以跳过这一层,然后爬只花费1个时间结点的这一层。最后只需要比较最后一次的跳跃的结果即可

完成代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int[] p = new int[10240]; //初始化值大,满足数模的要求
        int[] t = new int[10240];
        int[] arr = new int[10240];
        int n = sc.nextInt();
        for (int i = 1; i <= n; i++){
            arr[i] =sc.nextInt(); //存入到数组中
        }

        p[1] = arr[1]; // 第一层所花费的时间先存入
        for (int i = 2; i <=n; i++){
            p[i] = Math.min(p[i-1],t[i-1]) + arr[i]; //第一层爬和第一层跳先比,更新下一层的数据
            t[i] = Math.min(p[i-1],p[i-2]);// 比较前两层,取最小值,因为跳是不花费时间,于是t存的值实际上是前两次爬最优的解
        }


        System.out.println(Math.min(p[n],t[n]));
    }
}

测试结果:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Luca-s-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值