简化题意:
给定一长为 n n n 的有序序列 a a a,序列内元素两两不同。你现在有一个栈,初始为空,你会不断执行以下操作直到栈内元素之和 ≥ T \ge T ≥T ,其中 T T T 为给定值。问操作终止时进行操作次数的期望。一次操作过程如下:
- 如果栈不为空,则有 p p p 的概率弹出一个元素。
- 如果没弹,在所有 ≤ \le ≤ 栈顶元素的 a i a_i ai 里随机地取一个,将其入栈(不把入栈元素 a i a_i ai 删掉,下一次也可能继续入栈)。
首先栈内元素一定是有序的,因为每次入栈元素都不大于栈顶元素。也就是说,当前栈内状态如果是通过当前栈顶元素入栈得到的,而不是弹栈,那么可以唯一确定栈顶元素入栈前的栈内状态。当然,由当前栈内状态可以推出多个后继状态,包括弹栈,也就是由当前状态回到上一个状态。
将唯一的前驱状态看成父节点,将状态关系用图形表示,会形成一棵树,叶节点即为当前节点的状态已经满足元素之和 ≥ T \ge T ≥T 的节点。
如输入
0.5 3 2
1 2
![](https://img-blog.csdnimg.cn/direct/897778e49ac047ea8a7c1327d204bd13.png#pic_center)
由图可直观得出一次操作即在树上移动一步。
考虑 DP。设
d
p
x
dp_x
dpx 为到达当前的节点
x
x
x 的期望操作次数,
s
o
n
x
son_x
sonx 为
x
x
x 的后继状态,
c
n
t
x
cnt_x
cntx 为
x
x
x 的后继状态的个数。那么有:
d p x = p ∗ ( d p f a + 1 ) + ∑ y ∈ s o n x ( 1 − p ) ( d p y + 1 ) c n t x dp_x = p * (dp_{fa} + 1) + \sum_{y \in son_x} \frac{(1-p)(dp_y+1)}{cnt_x} dpx=p∗(dpfa+1)+y∈sonx∑cntx(1−p)(dpy+1)
化简可得:
d p x = p ∗ d p f a + 1 + ( 1 − p ) ∗ ∑ y ∈ s o n x d p y c n t x dp_x = p * dp_{fa} + 1 + \frac{(1-p)*\sum_{y\in son_x} dp_y}{cnt_x} dpx=p∗dpfa+1+cntx(1−p)∗∑y∈sonxdpy
上面的状态转移存在后效性,于是尝试从叶节点入手,当 x x x 为叶节点时,有状态转移:
d p x = p ∗ d p f a + 1 dp_x = p * dp_{fa} + 1 dpx=p∗dpfa+1
发现是 y = k x + b y = kx+b y=kx+b 的结构,可以用归纳法证明,可以将普通的节点也用父节点的状态表示:
假设当前节点 x x x 的子节点 y y y 可以用 x x x 的状态表示为 d p y = k y ∗ d p x + b y dp_y=k_y*dp_x+b_y dpy=ky∗dpx+by,于是有:
d p x = p ∗ d p f a + 1 + ( 1 − p ) ∗ ∑ y ∈ s o n x d p y c n t x ⟺ d p x = p 1 − 1 − p c n t x ∗ ∑ k y ∗ d p f a + 1 + 1 − p c n t x ∗ ∑ b y 1 − 1 − p c n t x ∗ ∑ k y dp_x = p * dp_{fa} + 1 + \frac{(1-p)*\sum_{y\in son_x} dp_y}{cnt_x}\Longleftrightarrow dp_x = \frac{p}{1-\frac{1-p}{cnt_x} * \sum{k_y}} * dp_{fa} + \frac{1+\frac{1-p}{cnt_x} * \sum{b_y}}{1-\frac{1-p}{cnt_x}*\sum{k_y}} dpx=p∗dpfa+1+cntx(1−p)∗∑y∈sonxdpy⟺dpx=1−cntx1−p∗∑kyp∗dpfa+1−cntx1−p∗∑ky1+cntx1−p∗∑by
由于 k y , b y k_y,\ b_y ky, by 已知,可以得出 k x , b x k_x,\ b_x kx, bx,证毕。
实现方面,考虑搜索,从根节点开始,递归至叶节点返回。