A. Buying Torches
先将(coal)视为(y)个(stick),然后就可以计算出想要完成任务至少需要多少个(stick),记为(need),然后计算至少多少次交易可以得到大于等于(need)个(stick),再加上用(stick)换取(k)个(coal)需要的交易次数即可。
B. Negative Prefixes
贪心地将较大的数放到更前面即可。
C. Mortal Kombat Tower
很有意思的dp。
现在假设(0)位置也有一个怪,然后你先把(0)位置的怪打了,这样子就可以将题目转化为你先手,朋友后手,朋友每一步的操作必须从你踩过的位置开始,你的每一步操作必须从朋友踩过的位置开始。
用(dp1_i)记录朋友走到(i)位置至少要花几个币,用(dp2_i)记录你走到(i)位置朋友至少要花几个币。
然后用(dp2_i)就可以更新(dp1_{i+1})和(dp1_{i+2}),用(dp1_{i+1})就可以更新(dp2_{i+2})和(dp2_{i+3}),用(dp1_{i+2})就可以更新(dp2_{i+3})和(dp2_{i+4})。
因为你或者朋友中的一个到达位置(n)就算通关了,所以最后的答案为(min(dp1_n, dp2_n))。
D. Trash Problem
记垃圾位置的集合为(pos),(delta)为(pos)的差分。
一次清扫操作可以合并两堆垃圾,代价为两堆垃圾之间的距离。
要将(i)处的垃圾到(j)处的垃圾合并,只需要端点开始,不断将当前者堆垃圾合并到下一堆垃圾上,直到合并到目标位置上,就可以取到最小代价,最小代价就是(|i - j|)。因为要想合并这些垃圾,每个(i)到(j)之间的(delta)都至少需要记一次。而这样子操作,每个(i)到(j)之间的(delta)就只需要记一次,而其他的操作都会存在记不止一次的(delta)。
且目标位置可以取(i)到(j)之间的任何位置,只要目标位置在这个范围里,将这个范围里的垃圾合并到目标位置的代价都是一样的。
如果完成任务的条件是最后只能有1堆垃圾,那么在最优的操作下,只需要(sum_i delta_i)的代价就可以完成。
现在是最后可以有两堆垃圾,其实就是有一个(delta_i)可以不计入答案,即最优的操作就是以这个delta为分界点,将左边的垃圾合并成一堆,将右边的垃圾合并成一堆。因为要使代价最小,所以最后的答案就是(sum_i delta_i - max_i delta_i)。