Wonderland【华为OD机试】(JAVA&Python&C++&JS题解)

148 篇文章 126 订阅 ¥9.90 ¥99.00

题目描述

Wonderland是小王居住地一家很受欢迎的游乐园。 Wonderland目前有4种售票方式,分别为一日票(1天)、三日票(3天)、周票(7天)和月票(30天)。
每种售票方式的价格将由一个数组给出,每种票据在票面时限内可以无限制的进行游玩。例如,小王在第10日买了一张三日票,小王可以在第10日、第11日和第12日进行无限制的游玩。
小王计划在接下来一年内多次游玩该游乐园。小王计划的游玩日期将由一个数组给出。 现在,请您根据给出的售票价格数组和小王计划游玩日期数组,返回完成游玩计划所需要的最低消费。
输入描述:
输入为2个数组
售票价格数组为costs,costs.length=4,默认顺序为一日票、三日票、周票和月票。
小王计划游玩日期数组为days,1<=days.length<=365,1<=days[i]<=365,默认顺序为升序。
输出描述:
完成游玩计划的最低消费
根据售票价格数组和游玩日期数组给出的信息,发现每次去玩的时候买一张一日票是最省钱的,所以小王会买8张一日票,每张5元,最低花费是40元。
示例1
输入:
5 14 30 100
1 3 15 20 21 200 202 230
输出:
40

解题思路

这个解决方案的步骤如下:

  1. 输入读取:

    • 将每种票的价格(一日票、三日票、周票和月票)读入pay数组。
    • minpay设置为票价中的最小值。
  2. 读取计划游玩日期:

    • 读取计划游玩日期直到输入结束,存入playday数组。
  3. 动态规划方法:

    • 初始化一个二维数组dp,用于存储从第i天到第j天的最低消费。dp[i][j]表示在这个范围内的最低消费。
    • dp[i][i]初始化为minpay,因为在单日游玩的最低花费就是最低票价。
  4. 动态规划计算:

    • 使用嵌套循环遍历计划游玩日期的所有子区间。
    • 计算dp[j][j+i],考虑在jj+i之间的所有可能拆分。
    • 通过考虑连续日期之间的最小花费,以及购买1、3、7或30天票是否更经济,更新dp[j][j+i]
  5. 输出:

    • 输出从第0天到第n-1天(n是计划游玩日期的数量)的最低消费。

关键思想是使用动态规划计算每个游玩日期子区间的最低消费,考虑不同的票选项。最终结果存储在dp[0][n-1]中,表示整个计划期间的最低消费。

题解代码

C/C++题解代码

#include <cstdio>
#include <iostream>
using namespace std;
 
int main() {
    int n=0, pay[4], playday[400], dp[400][400];
    cin >> pay[0] >> pay[1] >> pay[2] >> pay[3];
    int minpay = pay[0];
    if(pay[1] < minpay) minpay = pay[1];
    if(pay[2] < minpay) minpay = pay[2];
    if(pay[3] < minpay) minpay = pay[3];
    while (cin >> playday[n]) {
        dp[n][n] = minpay;
        n++;
    }
   
    for(int i=1;i<n;i++)
        for(int j=0;j<n-i;j++)
            dp[j][j+i] = dp[j][j+i-1] + dp[j+i][j+i];
            for(int k=j;k<j+i;k++)
                dp[j][j+i] = min(dp[j][j+i], dp[j][k] + dp[k+1][j+i]);
                int days = playday[j+i] - playday[j] + 1;
                if (days<=3) {
                    dp[j][j+i] = min(dp[j][j+i], pay[1]);
                }
                if (days<=7) {
                    dp[j][j+i] = min(dp[j][j+i], pay[2]);
                }
                if (days<=30) {
                    dp[j][j+i] = min(dp[j][j+i], pay[3]);
                }
            // printf("%d,%d=%d ",j,j+i,dp[j][j+i]);
            }
        }
    }
    cout<<dp[0][n-1];
    return 0;
}

Python题解代码

def calculate_min_cost(costs, playdays):
    n = len(playdays)
    minpay = min(costs)

    # Initialize a 2D array dp to store the minimum cost
    dp = [[0] * n for _ in range(n)]

    # Set the diagonal elements to minpay
    for i in range(n):
        dp[i][i] = minpay

    # Dynamic Programming calculation
    for i in range(1, n):
        for j in range(n - i):
            dp[j][j + i] = dp[j][j + i - 1] + dp[j + i][j + i]

            for k in range(j, j + i):
                dp[j][j + i] = min(dp[j][j + i], dp[j][k] + dp[k + 1][j + i])

            days = playdays[j + i] - playdays[j] + 1
            if days <= 3:
                dp[j][j + i] = min(dp[j][j + i], costs[1])
            if days <= 7:
                dp[j][j + i] = min(dp[j][j + i], costs[2])
            if days <= 30:
                dp[j][j + i] = min(dp[j][j + i], costs[3])

    return dp[0][n - 1]

# 输入售票价格数组和计划游玩日期数组
costs = list(map(int, input().split()))
playdays = list(map(int, input().split()))

# 计算并输出最低消费
result = calculate_min_cost(costs, playdays)
print(result)

JAVA题解代码

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = 0;
        int[] pay = new int[4];
        int[] playday = new int[400];
        int[][] dp = new int[400][400];

        for (int i = 0; i < 4; i++) {
            pay[i] = scanner.nextInt();
        }

        int minpay = pay[0];
        for (int i = 1; i < 4; i++) {
            if (pay[i] < minpay) {
                minpay = pay[i];
            }
        }

        while (scanner.hasNextInt()) {
            playday[n] = scanner.nextInt();
            dp[n][n] = minpay;
            n++;
        }

        for (int i = 1; i < n; i++) {
            for (int j = 0; j < n - i; j++) {
                dp[j][j + i] = dp[j][j + i - 1] + dp[j + i][j + i];

                for (int k = j; k < j + i; k++) {
                    dp[j][j + i] = Math.min(dp[j][j + i], dp[j][k] + dp[k + 1][j + i]);
                }

                int days = playday[j + i] - playday[j] + 1;
                if (days <= 3) {
                    dp[j][j + i] = Math.min(dp[j][j + i], pay[1]);
                }
                if (days <= 7) {
                    dp[j][j + i] = Math.min(dp[j][j + i], pay[2]);
                }
                if (days <= 30) {
                    dp[j][j + i] = Math.min(dp[j][j + i], pay[3]);
                }
            }
        }

        System.out.println(dp[0][n - 1]);
    }
}


JS题解代码

function calculateMinCost(costs, playdays) {
    const n = playdays.length;
    const minpay = Math.min(...costs);

    // Initialize a 2D array dp to store the minimum cost
    const dp = Array.from(Array(n), () => Array(n).fill(0));

    // Set the diagonal elements to minpay
    for (let i = 0; i < n; i++) {
        dp[i][i] = minpay;
    }

    // Dynamic Programming calculation
    for (let i = 1; i < n; i++) {
        for (let j = 0; j < n - i; j++) {
            dp[j][j + i] = dp[j][j + i - 1] + dp[j + i][j + i];

            for (let k = j; k < j + i; k++) {
                dp[j][j + i] = Math.min(dp[j][j + i], dp[j][k] + dp[k + 1][j + i]);
            }

            const days = playdays[j + i] - playdays[j] + 1;
            if (days <= 3) {
                dp[j][j + i] = Math.min(dp[j][j + i], costs[1]);
            }
            if (days <= 7) {
                dp[j][j + i] = Math.min(dp[j][j + i], costs[2]);
            }
            if (days <= 30) {
                dp[j][j + i] = Math.min(dp[j][j + i], costs[3]);
            }
        }
    }

    return dp[0][n - 1];
}

// 示例输入
const costs = [5, 14, 30, 100];
const playdays = [1, 3, 15, 20, 21, 200, 202, 230];

// 计算并输出最低消费
const result = calculateMinCost(costs, playdays);
console.log(result);


代码OJ评判结果

通过测试点

代码讲解

C/C++ 题解代码解析

  1. 变量和数组定义:

    • 使用 int n 记录计划游玩日期的数量。
    • 定义数组 pay 存储四种不同类型的票的价格。
    • 定义数组 playday 存储计划游玩的日期。
    • 定义二维数组 dp 用于动态规划。
  2. 输入:

    • 通过 cin 读取四种票的价格到数组 pay
    • 通过循环使用 cin 读取计划游玩的日期到数组 playday
  3. 计算最低票价:

    • 初始化 minpay 为第一种票的价格。
    • 遍历四种票的价格,更新 minpay 为最小的票价。
  4. 动态规划计算最低消费:

    • 使用动态规划填充二维数组 dp
    • 外层循环遍历游玩日期,内层循环进行动态规划计算。
    • 在计算过程中,考虑连续日期的最小消费以及购买不同类型票的情况。
  5. 输出:

    • 输出计算得到的最低消费。

Python 题解代码解析

  1. 函数定义:

    • 定义了一个名为 calculate_min_cost 的函数,用于计算最低消费。
  2. 变量和数组定义:

    • 使用 n 记录计划游玩日期的数量。
    • 计算四种票的最低价格,使用 minpay 存储。
    • 定义二维数组 dp 用于动态规划。
  3. 动态规划计算最低消费:

    • 使用动态规划填充二维数组 dp
    • 在计算过程中,考虑连续日期的最小消费以及购买不同类型票的情况。
  4. 输出:

    • 输出计算得到的最低消费。

Java 题解代码解析

  1. 变量和数组定义:

    • 使用 Scanner 读取输入。
    • 定义数组 pay 存储四种不同类型的票的价格。
    • 定义数组 playday 存储计划游玩的日期。
    • 定义二维数组 dp 用于动态规划。
  2. 输入:

    • 通过 Scanner 读取四种票的价格到数组 pay
    • 通过循环使用 Scanner 读取计划游玩的日期到数组 playday
  3. 计算最低票价:

    • 初始化 minpay 为第一种票的价格。
    • 遍历四种票的价格,更新 minpay 为最小的票价。
  4. 动态规划计算最低消费:

    • 使用动态规划填充二维数组 dp
    • 在计算过程中,考虑连续日期的最小消费以及购买不同类型票的情况。
  5. 输出:

    • 输出计算得到的最低消费。

JavaScript 题解代码解析

  1. 函数定义:

    • 定义了一个名为 calculateMinCost 的函数,用于计算最低消费。
  2. 变量和数组定义:

    • 使用 n 记录计划游玩日期的数量。
    • 计算四种票的最低价格,使用 minpay 存储。
    • 定义二维数组 dp 用于动态规划。
  3. 动态规划计算最低消费:

    • 使用动态规划填充二维数组 dp
    • 在计算过程中,考虑连续日期的最小消费以及购买不同类型票的情况。
  4. 示例输入和计算:

    • 提供了示例输入的数组 costsplaydays
    • 调用 calculateMinCost 计算最低消费并输出。

每种语言的代码都实现了相同的逻辑,使用动态规划来计算最低消费。不同之处在于语法和输入输出方式。

寄语

🚀✨ 朋友,希望你的华为OD机试就像是一场轻松的技术party!愿你的代码如同畅快的音符,跳跃在键盘上,最后弹奏出一曲高分之歌。加油,你是技术舞台上的巨星!通过机试,就像是风轻云淡,轻轻松松就把高分收入囊中。祝愿你的编程之旅一路顺风,破风前行,每一行代码都是成功的注脚!🌈💻

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值