编辑代码

const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
// 问题描述:
// 有4种通行证可选:1天、3天、7天、30天
// 每种通行证有不同的价格
// 给定需要出行的日期
// 需要找出购买通行证的最小花费方案
// 输入处理:
// costs:包含4个数字的数组,表示不同天数通行证的价格
// days:需要出行的日期数组
// maxDay:最后一天,用于确定dp数组大小
// 动态规划:
// 使用dp数组记录到每天为止的最小花费
// dp[i]表示到第i天为止的最小花费
// 初始值都设为0
// 状态转移:
// 对于每个需要出行的日期:
// 计算四种购买方案的花费
// 选择花费最小的方案
// 对于不需要出行的日期:
// 保持前一天的花费不变
// 购买方案:
// 买1天通行证:dp[i-1] + costs[0]
// 买3天通行证:dp[i-3] + costs[1](如果天数足够)
// 买7天通行证:dp[i-7] + costs[2](如果天数足够)
// 买30天通行证:dp[i-30] + costs[3](如果天数足够)
// 结果输出:
// 输出最后一天的最小花费
// 这个实现使用动态规划算法有效地解决了通行证购买优化问题,时间复杂度为O(maxDay),其中maxDay是最后一天。代码结构清晰,注释详细,便于理解和维护。
void (async function () {
  // 读取输入:
  // costs: 包含4个数字的数组,分别表示1天、3天、7天、30天通行证的价格
  const costs = (await readline()).split(" ").map(Number);

  // days: 需要出行的日期数组
  const days = (await readline()).split(" ").map(Number);

  // 获取最后一天,用于确定dp数组的大小
  const maxDay = days[days.length - 1];

  // 创建dp数组,dp[i]表示到第i天为止的最小花费
  const dp = new Array(maxDay + 1).fill(0);

  // 用于遍历days数组的索引
  let idx = 0;

  // 动态规划主循环
  for (let i = 1; i <= maxDay; i++) {
    // 如果当前日期是需要出行的日期
    if (i == days[idx]) {
      // 计算四种购买方案的花费:
      // 1. 买1天通行证
      const buy1 = dp[i - 1] + costs[0];

      // 2. 买3天通行证(如果天数足够)
      const buy3 = (i >= 3 ? dp[i - 3] : 0) + costs[1];

      // 3. 买7天通行证(如果天数足够)
      const buy7 = (i >= 7 ? dp[i - 7] : 0) + costs[2];

      // 4. 买30天通行证(如果天数足够)
      const buy30 = (i >= 30 ? dp[i - 30] : 0) + costs[3];

      // 选择四种方案中花费最小的一个
      dp[i] = Math.min(buy1, buy3, buy7, buy30);

      // 移动到下一个需要出行的日期
      idx++;
    } else {
      // 如果不是需要出行的日期,花费保持不变
      dp[i] = dp[i - 1];
    }
  }

  // 输出最后一天的最小花费
  console.log(dp[maxDay]);
})();