华为OD机试E卷 - Wonderland(Java & Python& JS & C++ & C )

这篇博客介绍了华为OD机考中的一道题目,涉及Wonderland游乐园的四种售票方式。博主提供了根据售票价格和游玩日期计算最低消费的动态规划解题思路,并给出了C++、Java、JavaScript、Python和C语言的代码实现。文章包含多个测试用例以展示解决方案的正确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

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,默认顺序为升序。

输出描述

完成游玩计划的最低消费。

用例

输入 5 14 30 100
1 3 5 20 21 200 202 230
输出 40
说明 根据售票价格数组和游玩日期数组给出的信息,发现每次去玩的时候买一张一日票是最省钱的,所以小王会卖8张一日票,每张5元,最低花费是40元

解题思路

我们可以使用动态规划。核心思想是为每个游玩日期计算最低消费成本,并存储这些结果以供后续日期使用。具体步骤如下:

  1. 创建一个数组 dp 以存储直至每一天的最低消费。数组的长度为365天加1(因为数组是从0开始的,而天数是从1开始的)。
  2. 初始化 dp[0] = 0,因为在开始之前没有任何消费。
  3. 遍历每一天,对于每一天,我们有几种选择:
    • 如果这一天不在计划游玩日期中,则这一天的消费与前一天相同,即 dp[i] = dp[i-1]
    • 如果这一天在计划游玩日期中,我们需要考虑三种票价中的最低消费:
      • 一日票的消费是:dp[i-1] + costs[0]
      • 三日票的消费是:dp[max(i-3, 0)] + costs[1]
      • 周票的消费是:dp[max(i-7, 0)] + costs[2]
      • 月票的消费是:dp[max(i-30, 0)] + costs[3]
    • 对于这一天,选择上述四种情况中的最小值作为 dp[i]
### 华为OD Java 题及解答 #### 题目一:云短信平台优惠活动 该题目要求设计并实现一个用于处理云短信平台优惠活动的功能模块。具体需求包括但不限于创建、查询和管理各种类型的优惠活动。 ```java public class CloudSmsPromotion { private Map<String, Promotion> promotions; public void addPromotion(Promotion promotion) { this.promotions.put(promotion.getId(), promotion); } public List<Promotion> getActivePromotions() { return this.promotions.values().stream() .filter(Promotion::isActive) .collect(Collectors.toList()); } } ``` 这段代码展示了如何定义 `CloudSmsPromotion` 类来管理和操作促销对象[^1]。 #### 题目二:Wonderland 游玩成本最小化问题 给定售票价格数组 `costs` 和小王计划游玩日期数组 `days`,目标是在满足所有出行天数的前提下使总花费最少。这里提供了一种动态规划的方法解决这个问题: ```java import java.util.*; class Solution { int[] durations = new int[]{1, 3, 7, 30}; // 对应四种票的有效期 public int minCostTickets(int[] days, int[] costs) { Set<Integer> daySet = Arrays.stream(days).boxed().collect(Collectors.toCollection(TreeSet::new)); Integer[] dp = new Integer[366]; dp[0] = 0; for (int i = 1; i <= 365; ++i){ if (!daySet.contains(i)){ dp[i] = Objects.requireNonNullElseGet(dp[i - 1], () -> 0); continue; } dp[i] = Math.min( Math.min(costs[0] + Objects.requireNonNullElseGet(dp[Math.max(0, i - durations[0])], () -> 0), costs[1] + Objects.requireNonNullElseGet(dp[Math.max(0, i - durations[1])], () -> 0)), costs[2] + Objects.requireNonNullElseGet(dp[Math.max(0, i - durations[2])], () -> 0)) ); } return Objects.requireNonNullElseGet(dp[365], () -> 0); } } ``` 上述解决方案利用了动态规划的思想,通过构建状态转移方程实现了最优解计算[^4]。 为了更好地准备华为OD中的Java部分,建议考生熟悉常见的算法模式如贪心法、回溯法以及图论等问题,并掌握常用的数据结构及其应用技巧。此外,多做练习题也是提高编程能力的重要途径之一[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

算法大师

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

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

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

打赏作者

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

抵扣说明:

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

余额充值