Codeforces Round #711 实录

【A】

记得用ll

感觉不会修改很多次就能出解。

【B】

单纯的装箱是需要DP,甚至是NP-hard的

但是这里都是2^x

每一行显然留得空越少越好

W二进制分解,从高位的1开始往下走,把wi从大到小排序,找到能放的就把wi放在这个位置上。

一轮完了,还有wi没放,重头开始。

O(N)

不对,是一个我不知道怎么证明的贪心

但是,因为是二进制,可能这样做是对的。

TLE,我艹

首先贪心算法能达到最少空间,这是没问题的,二进制的特性。

接下来就是优化模拟。

感觉焦虑万分。。

等等,找到公式了。。

又WA了一发,这把要崩盘啊。。冷静一下。。分析问题

w不是2^x

直接用堆可以的吧。。

对每个元素,找一个>=它的最小的元素,嗯,好像是multiset吧。。

终于A了。。原来是这个路子。。一开始第一感觉错了啊。

【C】

有趣的题,一定是DP和贡献法

转换一下视角,题目描述太动态了。

方向应该都可以改为同向。对称性。

DP顺序条件不够好

感觉挺裸的DP啊。。

【D】

感觉有点张成空间的味道,毕竟系数你可以自己选。

感觉很诡异啊。。分数形式都出来了。。还TM弄个取整,恶心死我。。

分母固定。

k 单调不减

 

赛后:感觉身体被掏空。

【B】这题竟然用了将近1h做出来,第一直觉如果错了真的血崩,其实主要还是贪心算法,不容易证明正确性,自己却愿意骗自己,认为自己已经想对了(不然意味着你还得花不确定的时间想新的算法)。

看了题解,的确是用调整法,使用调整法的着力点是二进制的一个性质:

如果a1+...+ak>x,其中ai都是二次幂,从大到小,且a1<=x,那么必然存在一个l<k,使得a1+...+al=x,也就是存在==x的前缀。

然后我们的算法是,把块按大小排序(从大到下),对当下的箱子,找到长度能容纳它的长度最小的箱子塞,否则加一个新箱子塞。

首先,哪个块先塞是无所谓的,块与箱子的对应关系才是matter的,假设有一个方案,把当前块X不是塞进了长度能容纳它的长度最小的箱子A,那么有两种可能:

后续塞到A的块的长度之和Y<X,那么我们把这些块与Y在该方案中塞到的箱子的位置,进行swap,显然是可行的,且不改变箱子总数。

后续塞到A的块的长度之和Y>=X,利用上面提过的性质,这些块一定可以选出若干,其和恰好=X,那么也可以把这些块与X的位置进行swap。

所以我们的算法总是不破坏最优解。调整成功。

现在来证明这个性质:

用数学归纳法,设对于k-1的情况,式子成立,那么对于k的情况,因为x>=a1,可以把x写成x=2^m*a1, m>=1(显然m=0那么直接取a1)

因此,用掉一个ai后,就转化为x'=x-a1,  a2+...+ak>x'的问题。(依然有x'>=a2)

于是这个性质是成立的。

(感觉我不能主动地使用数学归纳法。。这是硬伤,只能等别人告诉我要用数学归纳法,然后我才会试着证明)

【D】因为m太大以至于我一上来就开始想可行的算法,但是却没考虑过纯粹的暴力。因为什么取整啊,分数啊,恶臭至极,让人无从下手,那么先抛开数据范围不管,想一个多项式时间的暴力是有必要的。(起码这是O(NM^2)的暴力,而不是那种爆搜的O(2^N)的暴力),有了暴力算法就有前进的基地,一般而言,正解可能与暴力完全不相干,但是这里却是对暴力的优化。

暴力就是,在每一个时间,维护从一开始,经过某些系数的选择,可以达到的数字的集合,那么下一时间,就是从这些数字集合中再次张成新的数字集合。

因为,我们的操作,是可以平等地施加给集合中的每个元素的,因此,我们如果对一个数字k1,施加了一些操作,得到了k2,其中k2在之前就存在于集合内,那么我们就不需要继续对k1施加新的操作了。

因为,当我们对k2施加操作的时候,形成的数字包含了k1继续操作所能形成的数字。(也算是一种单调性吧,集合包含关系的单调性)

去除重复的访问后,因为我们能形成的数字都在m之间(外面的不需要管),而且不重复访问,那么每次,之前未被访问的点最多被访问过一次,已经被访问的过点,最多访问两次,一次是从它出发,另一次是被更小的生成,所以每次的访问数量是O(M)的,整体就是O(NM)。

这种题。。说不出的滋味。。画风太奇怪了。。影响我的判断力。。

posted @ 2021-03-30 00:36  AngelKnows  阅读(72)  评论(0)    收藏  举报