【学习笔记】P7961 [NOIP2021] 数列
学习的是这篇优秀的题解(不)
学习的是这篇优秀的题解(是)
学习的是这篇优秀的题解(原)
学习的是这篇优秀的题解(创)
学习的是这篇优秀的题解(!)
题目传送门
20 pts
思路
爆搜,枚举每个数的每种取值。
复杂度 \(\Theta(m^n)\)
50 pts
思路
爆搜+记忆化
复杂度 \(\Theta(n^2 \times 2^m \times m)\)
正解
思路
思考一下,这道题最阴的地方在于什么?
在于进位!
赛场上,就是因为进位,我才甚至连一丁点部分分都不敢考虑(还是蒻诶,AFO了)
而我们知道,进位的原则是由低位向高位进位的,而不是反过来。
而这就是DPの无后效性的体现!
于是想到DP
最原始的状态为设置一个 \(DP(x,y)\) ,表示当前已经处理了 x 位,已经用了 y 个数的状态
很自然地,\(DP(x,y)=\sum\limits^{n-y}_{i=0}DP(x+1,y+i)\) ,其中 i 表示这一位上将放置 i 个 1。
这时候就会发现,对于进位问题还是没有任何进展。
但是,摊煎饼果子的过程(啊我只能想到这个)启发了我们(怎么启发?很简单,在考试的时候申请出去买一个(大雾)),因为毕竟DP一定会推到最后一位,所以可以统计堆积在某一位上的 1 的个数,在转移的时候进行处理。
于是,多了一个 b
更加自然地, \(DP(x,y,b)=\sum\limits^{n-y}_{i=0}DP(x+1,y+i,\left\lfloor\dfrac{b+i}{2}\right\rfloor)\)
为什么 b 这么转移呢?很简单,因为在原来堆积了 b 个数的基础上,又来了 i 个 1,而每两个 1 会进一位,所以就这么处理了。
不过,众所周知,不是只要搜到最后就是合法的,题目还有一个限制,叫作“二进制表示中 1 的个数不超过 k 时”
当然,大家肯定注意到了。前面用的是“b”。
那么“a”在哪里?
这个时候,我们就会愉快地思考怎样进行判断。
还是摊煎饼果子的过程启发了我们(真是实用呢),我们发现,以摊子(我也不知道这叫什么)为界,b 已经统计出了堆在摊子后面的糊糊(当然,还没有摊开,所以要自己写函数统计二进制中 1 的个数),而我们只需要一个 a 来统计一下前面已经摊开的 1 的数量即可。
最最自然地, \(DP(x,y,a,b)=\sum\limits^{n-y}_{i=0}DP(x+1,y+i,a+((b+i) \mod 2),\left\lfloor\dfrac{b+i}{2}\right\rfloor)\)
为什么 a 这么转移呢?更好理解,因为众所周知,你买的煎饼果子都是摊得不均匀的(b+i)在进位的时候,如果有偶数个1,一定会全部进位,不会产生更多贡献,反之则会产生 1 的贡献。
然后,复杂度是 \(\Theta(m \times n^4)\)
然后就没有然后了。