钟xxx


私信TA

用户名:dotcpp0661013

访问量:1782

签 名:

等  级
排  名 1587
经  验 2766
参赛次数 0
文章发表 23
年  龄 0
在职情况 学生
学  校
专  业

  自我简介:

解题思路:
微信图片_20240123195112.png

微信图片_20240123195721.png

注意事项:

参考代码:

import java.util.Map;
import java.util.Scanner;

/**
 * 这天,一只蜗牛来到了二维坐标系的原点。
 * 在 x 轴上长有 n 根竹竿。它们平行于 y 轴,底部纵坐标为 0,横坐标分别为 x1, x2, ..., xn。
 * 竹竿的高度均为无限高,宽度可忽略。蜗牛想要从原点走到第 n 个竹竿的底部也就是坐标 (xn, 0)。
 * 它只能在 x 轴上或者竹竿上爬行,在 x 轴上爬行速度为 1 单位每秒;
 * 由于受到引力影响,蜗牛在竹竿上向上和向下爬行的速度分别为 0.7 单位每秒和 1.3 单位每秒。
 * 为了快速到达目的地,它施展了魔法,在第 i 和 i + 1 根竹竿之间建立了传送门(0 < i < n),
 * 如果蜗牛位于第 i 根竹竿的高度为 ai 的位置 (xi , ai),就可以瞬间到达第 i + 1 根竹竿的高度为 bi+1 的位置 (xi+1, bi+1),
 * 请计算蜗牛最少需要多少秒才能到达目的地。
 */
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] x = new int[n];
        // 表示的是第i个竹竿和前一个的距离
        for (int i = 0; i < n; i++) {
            x[i] = sc.nextInt();
        }
        if (n == 1){
            System.out.printf("%.2f", (double)x[0]);
            return;
        }
        int[] a = new int[n - 1];
        int[] b = new int[n - 1];
        // 实际上是最后一根不需要魔法,顶多只会爬下来
        for (int i = 0; i < n - 1; i++) {
            a[i] = sc.nextInt();
            b[i] = sc.nextInt();
        }
        double vX = 1, vUp = 0.7, vDown = 1.3;
        double[][] dp = new double[n][2]; // 0表示到达y0,1表示到达魔法该到达的起始位置。
        // 第一个竹竿无论用不用魔法,都是x[0] / vX
        dp[0][0] = x[0] / vX;
        dp[0][1] = x[0] / vX + a[0] / vUp;
        for (int i = 1; i < n - 1; i++) {
            // 这个表示到达第i根竹竿最低端所需的时间
            int dis = x[i] - x[i - 1];
            // 底端的值要么是前一个底端的加距离,要么是前一个的魔法位置爬下来之后的时间。
            // 实际上使用了魔法的话,就相当于不走x轴了,直接从魔法位置爬下来。
            dp[i][0] = Math.min(dp[i - 1][0] + dis / vX,dp[i-1][1] + b[i - 1] / vDown);
//            System.out.println(dp[i][0]);
            // 如果是魔法位置的话,实际上就是本身的底端爬到对应的位置,或者是
            // 前一个的魔法位置爬到自己所对应的魔法位置的时间
            double timeGap = 0;
            // 如果前一个的位置的魔法结果要比自己应该在的魔法初始位置要矮的话,那么要往上爬
            if (a[i] > b[i - 1]){
                timeGap = (a[i] - b[i - 1]) / vUp;
            } else {
                timeGap = (b[i - 1] - a[i]) / vDown;
            }
            dp[i][1] = Math.min(dp[i][0] + a[i] / vUp, dp[i-1][1] + timeGap);
//            System.out.println(dp[i][1]);
        }
        // 最后一步是特例,提出来判断
        dp[n - 1][0] = Math.min(dp[n - 2][0] + (x[n - 1] - x[n - 2]) / vX, dp[n - 2][1] + b[n - 2] / vDown);
        dp[n - 1][1] = Math.min(dp[n - 1][0], dp[n - 2][1] + b[n - 2] / vDown);
        System.out.printf("%.2f", dp[n - 1][0]);

    }
}


 

0.0分

6 人评分

  评论区

  • «
  • »