sequence题解(贪心)

来源:互联网 发布:c语言游戏开发视频 编辑:程序博客网 时间:2024/05/18 00:27

[题目描述]

      给你一个序列,你可以给某个数*2或给所有数-1,求最短的把所有的数都变成0的操作序列.

[题解]

      这道题原本是北京集训的题目,被某某人邪恶的蒯来做noip模拟题.

      这道题奇特的地方是,操作中有*2,但又不能直接用二进制搞(因为还有个-1).

      一个显然的结论是,在变换的过程中所有的数都不能超过原来的最大的数(如果你看不懂,就继续看后面,应该就会懂了).

      由于所有元素减一的次数是一样的,所以最优方案一定是所有元素都减少MAXN次(证明看后面).

      基于直觉或者说经验,我们提出这样一种方法:每个元素都减少MAXN,并适当的*2以使最后的序列变成0

      我们考虑*2的次数.显然,*2次数的下界是[log(maxn/ai)](取上整).其次,用[log(maxn/ai)](取上整)次*2操作与MAXN次-1操作一定可以把一个数变成0.

      假设先把2都乘上去,最后再减一,那么最后的数有可能大于0.考虑把第一个-1操作前移,我们发现,当它前移一位,-1变成-2,移2位,-2变成-4...由于最后的数<maxn,所以它一定可以用不超过log(MAXN)位的二进制数来表示,并且-1的数量必然大于*2的数量,因此必然可以构造这样的方案,使得只要用log(maxn/ai)次乘法与maxn次加法就可以使ai变成0.

      有了这个方案,我们很容易就能证明:这种方案在-1的次数一样的情况下一定是最优的.由于这个方案的-1次数已经到达了下界,我们考虑减一次数更多的方案.

      显然,-1次数更多必然使得过程中的最大数超过maxn.令这个最大的数为新的maxn,通过上面的方法又可以构造出一个可能的最优方案.显然,新方案不会比旧方案优.上面讲的第一,二个结论也就得出来了.

      这道题目其实不难.但是考试时被第二题恶心到了,第一题一开始想用2进制来分析,浪费了很多时间.今天考试时状态还是不太好.


BY QW

转载请注明出处

原创粉丝点击