提示 1: 一般促销是买得越多单价越便宜,怎么根据这个逻辑调整?
提示 2: 容量总为
提示 3: 如果已经调整为更大量的商品更便宜,接下来应该怎么购买?
我们先依据提示 1 进行调整。由于
于是大份柠檬水的价格应该不超过小份柠檬水的两倍,否则应该用两份小的柠檬水凑。
按照上述逻辑,我们假设
于是,
因此这样调整后,最大的包装单价最低。
整体上很像一个无套利条件。
接下来,我们要使得购买的柠檬水总量不小于
这里使用了贪心。为何这题贪心成立呢?在购买的总柠檬水一定时,选择更大量的柠檬水一定更好。
因为首先其单价更低,而如果不使用更大量的柠檬水,将需要一批更小量的柠檬水凑成同样的数量(因为从小到大的容量满足倍数关系),这样单价是更高的。
于是,我们从后往前贪心地买尽可能多的柠檬水,使得总量不超过
而这样,在遍历每个位置时会剩下一些柠檬水。除了剩下的柠檬水外,前面的贪心逻辑使得前半部分的单价是最低的。
而每次剩下的柠檬水有两种凑法:用更小的容量凑 / 直接用当前的容量凑(会使得购买总量可能大于
为什么这样做有道理呢?我们假设我们最后购买了
而在上述过程中,我们 “用当前容量凑” 的过程,相当于枚举了所有可行的
如果上述过程不太理解,可见代码。时间复杂度为
def main():
n, l = MII()
nums = LII()
for i in range(1, n):
nums[i] = min(nums[i], nums[i-1] * 2)
ans = inf
cur = 0
for i in range(n - 1, -1, -1):
ans = min(ans, cur + nums[i] * ((l - 1) // (1 << i) + 1))
v = l // (1 << i)
l -= v << i
cur += v * nums[i]
print(ans)