Educational Codeforces Round 95 (Rated for Div. 2)/Codeforces 1418 ABCD

AC代码

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)

原文地址:https://www.cnblogs.com/zengzk/p/13673122.html