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]);
})();