2048曾经是一款风靡全球的小游戏。
今天,我们换一种方式来玩这个小游戏。
你有一个双端队列,你只能把元素从左端或从右端放入双端队列中。一旦放入就不得取出。放入后,若队列中有连续两个相同的元素,它们将自动合并变成一个新的元素——原来那两个元素的和。若新的元素与它相邻的元素相同,则继续合并……
如:双端队列中有2, 4, 16三个元素。若将2从左端插入双端队列中,该队列将变成8, 16。若将2从右端插入双端队列中,该队列将变成2, 4, 16, 2。
一开始,双端队列为空。我们将给你一些数,你需要依次插入到双端队列中。问是否存在一种操作方案,使得双端队列最后只剩下一个数。
\(1\le n\le 1000,\space \sum\limits_{i=1}^{n}a_i\le 2^{13},\space T\le 10000\),其中 \(n\gt 20\) 的数据不超过 \(150\) 组。
小学生手玩 \(1s\) 可得:如果一个数被夹在两个大于它的数中间,最后队列里就至少剩下 \(3\) 个数。
也就是说,任何时刻队列一定是单峰的,峰左边的数单调递增,峰右边的数单调递减。
观察 \(a_i\),发现不仅都是 \(2^k\),而且总和 \(\le 2^{13}\),那是不是随便二进制状压一下两边的数就行了?
状压显然可行,因为每个数在每一边的出险次数都是 \(0\) 或 \(1\),如果出现了 \(2\) 次,由于数列单调,这两个数相邻,所以会拼成一个更大的数。而每个数直接对应一个二进制位,拼两个数根本不用任何特殊操作,直接加上新来的数就自动进位了。
然而因为有 \(1w\) 组数据,复杂度貌似不太支持把两边都状压。
考虑可不可以只状压左边,把右边用左边的状态表示出来。不难发现由于是依次加入数,我们每次加入一个数后都知道所有加入的数之和,用总和减去左边的数之和 就是右边的数之和了。
原文:https://www.cnblogs.com/scx2015noip-as-php/p/cerc2014e.html