分手是祝愿

这种可能会有无穷的情况,就是对某一个开关一直按

像这种题目我把他叫做无穷型嵌套期望

这种题目一般都是用DP推出公式然后化简

来看这道题目

首先,我们考虑假设最开始最少的操作不超过k,应该怎么做

很容易发现一个性质,就是按动一个开关,只能影响前面的开关,不能影响后面的开关

这是什么?无后效性!就跟DP一样,我们以后遇到这种情况,就要从前往后(这题是从后往前)考虑

我们从后往前考虑(因为这题很显然每个开关最多按一次,而且按得顺序没有关系),假设对当前考虑的这个开关,后面的开关的按动情况都已经决定了,那么是否按当前这个开关只用看他是否开即可。然后一个序列的最小操作就是唯一的

那如果这个唯一的操作比k大怎么办?

为了行文方便,我们规定对一个序列的最小的操作序列(与“序列”区分,序列表示的是灯的开关的情况,操作序列表示这个序列的操作方法)是01串,0表示不按动,1表示按动

首先,这里是完全随机地按动开关

意味着如果对多个序列,这些序列的操作序列的1的个数(大于k)相同,他们到达只有k个1的期望步数是相同的(相当于这些序列是“完全等价”的,可以都把这些序列想象成前面全是0后面全是1,很显然是相同的步数)(注意,一个序列操作一次,如果是操作的是操作序列的1的位置,那么对于新的序列,我们重新执行一次从后向前的扫描的算法,我们会发现新的操作序列的1的个数刚好少一;而如果是操作的是操作序列的0的位置,那么对于新的序列,我们重新执行一次从后向前的扫描的算法,我们会发现新的操作序列的1的个数刚好多一)(其实这里更简单的理解方式是利用操作的无序性,因为不用考虑顺序,所以无论先按哪个按钮,操作序列剩余的序列显然都不变)

所以我们设f[i]表示从i1走到k1的期望步数

注意,这是这类题非常重要的一个性质。因为有i1的序列太多太多了,我们要想用一个f[i]表示,那么一定要保证每种情况的f[i]是相同的。其他嵌套期望类似(我们是没有办法存储每一个序列的,这样复杂度会爆炸,我们必须要想办法利用更简单的状态去描述每一个序列,这就要找不同序列的相同点:我们考虑对任何一个序列操作一次,其操作序列的1的个数要么多一要么少一,而且我们发现当操作序列的1的个数相同时期望就相同。所以我们可以用操作序列的1的个数来描述状态)

于是有f[i]=inf[i1]+ninf[i+1]+1

注意这是第二个性质,在写公式的时候,一定不要让f[i]同时需要两个方向的f,因为这两个方向的f同样需要f[i],是没办法递推的(其实这里主要是n的范围太大了,导致没办法用高斯消元,所以尽量考虑直接用递推,也许也可以就手动消元,但是挺复杂的(而且手动消元也就只能降一次变成二次,这里显然要求线性复杂度),所以以后无穷DP如果要TLE的话就考虑手动消元或者换状态吧)

这里我们换一个状态,设f[i]表示从i1变成i11的期望步数(所以以后考虑两种状态:一种是直接走到终点,另一种是走到下一步)

然后剩下看洛谷题解吧

update 2024.8.14

应该存在这个讨论说的问题,这个讨论中给的那个题解应该才是正确理解方式。算不出来的时候就像这种设差吧

posted @   最爱丁珰  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示