期末总结

序列 dp

woc 之前写的什么玩意

LIS

首先是正常的 dp。

\[f_i=\max\limits_{a_j<a_i,1\leq i<j}\{f_j+1\} \]

memset(f, 1, sizeof f);
for(int i = 2; i <= n; i++)
    for(int j = 1; j < i; j++)
        if(a[j] < a[i])
            f[i] = std::max(f[i], f[j] + 1);

然后是二分优化。

\(d_i\) 表示长度为 \(i\) 的 LIS 末尾元素最小值。

  • \(a_i>d_{size}\)\(size:=size+1\)
  • 否则替换掉 \(d\) 中第一个大于 \(a_i\) 的元素。

时间复杂度 \(O(n \log n)\)

d[1] = a[1];
for(int i = 2; i <= n; i++)
    if(a[i] > d[sz]) d[++sz] = a[i];
	else *std::upper_bound(d + 1, d + sz + 1, a[i]) = a[i];

然后是树状数组优化。

发现其实是一个 \(i < j, a_i<a_j\) 的二位偏序问题。

树状数组 \(f\) 维护前缀最大值。

for(int i = 1; i <= n; i++) {
    f[i] = query(a[i] - 1) + 1;
    modify(a[i], f[i]);
}

同理,还可以用可爱的线段树。

LDS 同理。

LCS 不好玩。不写了。

P1106 低价购买

求最长下降子序列的长度及方案数。

先求出最长下降子序列的长度 \(f\)

\[\forall 1\leq j<i:\quad \begin{cases} cnt_i:=cnt_i+cnt_j&f_i=f_j\\ cnt_i=cnt_j&f_i>f_j \end{cases} \]

同理,可以使用树状数组优化。

在维护前缀最大时维护上述方案数。

可以将时间复杂度从 \(O(n^2)\) 降到 \(O(n\log n)\)

序列 dp 里有许多规律。一个 dp 式的策略往往可以从另一个 dp 式的策略得到。

将两个式子一起转移即可。

背包 dp

感觉模板不难。直接上 Tricks。

下文中 \(v\) 表示体积,\(w\) 表示价值。

单调队列优化多重背包

md 之前写的什么煞笔玩意 重构

多重背包朴素转移为

\[f_{i,j}=\max\limits_{k=0}^{cnt_i}f_{i-1,j-v_ik}+w_ik \]

观察发现转移中的的第二维 \(j-w_ik\equiv j\pmod{w_i}\),即 \(f_{i,j+w_ik}\) 能被 \(f_{i,j}\) 转移。

故对于每个物品,可以对其代价按照 \(\pmod{w_i}\) 分组。

\(v=v_i,c=\lfloor\frac{j}{v}\rfloor,d=j\bmod v\)

\(j=vc+d\)

\(v,c,d\) 带入朴素方程,得:

\[j-vk=vc+d-vk=v(c-k)+d \]

不难发现 \(c-k\) 就是在限制内还没有选的物品数量,令其为 \(k'\)

故有

\[\begin{align*} f_{i,j}&=\max\limits_{k=0}^{cnt_i}\{f_{i-1,k'v+d}+w_ic-w_ik'\}\\ &=\max\limits_{k=0}^{cnt_i}\{f_{i-1,k'v+d}-w_ik'\}+w_ic \end{align*} \]

由于 \(k\) 的取值范围一定,\(c\) 为定值,所以 \(k'\) 的取值范围也一定。

可以考虑使用单调队列优化。

区间 dp

区间 dp,顾名思义,其本质是在大区间内枚举断点,将其分成两个小区间后选择最优方案进行转移。

特点为从小区间转移至大区间,自底向上求值

通项公式为 \(f_{l,r}=\max\limits_{k=l}^{r-1}f_{l,k}+f_{k+1,r}+w_{l,r}\)

主要 dp 板块需要借助题目感性理解一下。不然会很抽象。

下方由主观难度由易到难排序。


T1. [CQOI2007] 涂色

题目传送门

设状态 \(f_{l,r}\)\([l,r]\) 内的最少涂色次数。

初始化 \(f_{i,i}=1\)\(f_{i,i+1}=\begin{cases}2&s_i\neq s_{i+1}\\1&s_1=s_{i+1}\end{cases}\)

显然,若两次涂色有重合部分,必然不是最优解。

枚举断点 \(k\),有转移方程 \(f_{l,r}=\min\limits_{l+1}^{r-1}f_{l,k}+f_{k+1,r}\)

特判一下 \(s_l=s_r\) 的情况。 此时可以发现 \(f_{l,r}\)\(f_{l+1,r}\)\(f_{l,r-1}\) 等价。即 \(f_{l,r}=f_{l+1,r}=f_{l,r-1}\)

\[f_{l,r}=\begin{cases}\min\limits_{l+1}^{r-1}f_{l,k}+f_{k+1,r}&s_l\neq s_r\\\min\{f_{l+1,r},f_{l,r-1}\}&s_l=s_r\end{cases} \]

T2. 表达式的亿种可能性

题目传送门

\(A\)\(f_{l,k}\) 所有运算顺序结果的集合,\(B\)\(f_{k+1,r}\) 所有运算顺序结果的集合。令 \(|A|=p,|B|=q\)

\[f_{l,r}=\begin{cases}\sum\limits_{i=1}^p\sum\limits_{j=1}^q(A_i+B_j)&op_k=+\\\sum\limits_{i=1}^p\sum\limits_{j=1}^q(A_i-B_j)&op_k=-\\\sum\limits_{i=1}^p\sum\limits_{j=1}^qA_iB_J&op_k=\times\end{cases} \]

\[f_{l,r}=\begin{cases}q\times f_{l,k}+p\times f_{k+1,r}&op_k=+\\q\times f_{l,k}+p\times f_{k+1,r}&op_k=-\\f_{l,k}\times f_{k+1,r}&op_k=\times\end{cases} \]

由于 \(f_{l,r}=\{A_1,A_2,\cdots A_p\}op_k\{B_1,B_2,\cdots B_q\}\),即只要保证 \(A,B\) 的内部顺序不变,可以将 \(A,B\) 任意穿插,共有 \(C^p_{p+q}\) 种顺序。

故要给 \(f_{l,r}\) 乘上系数 \(C^p_{p+q}\)

时间复杂度 \(O(n^3)\)

T3. [JXOI2018] 守卫

题目传送门

这题主要是状态转移的细节不太好理解。

但是是第一道单切紫题,好诶 所以就把题解粘上来了

设状态 \(f_{l,r}\) 为在区间 \([l,r]\) 内要放的最少保镖数量。

看到题面第一眼的感觉是不会判两点能否连接。

第二眼发现可以用斜率判。

\(k_{l,r}\) 为横坐标为 \(l,r\) 的两点连线斜率。

\(k_{l,r}=\frac{h_r-h_l}{r-l}\)

手搓几组样例,得 \(\forall x\in[l,r)\),有 \(k_{l,r}<k_{x,r}\)即对于 \(x\in[l,r)\)\((x,r)\) 的连线斜率最小。

且若 \(a\) 对于 \(b\) 可见,并满足 \(h_c>h_b\)\(c>a\),则 \(a\) 对于 \(c\) 可见。

\(p=\{p_1,p_2\cdots p_m\}\)\(r\) 点当前能够覆盖的点集。注:下文中 \(p\) 按照从右至左斜率单调递减的顺序排序。

注:能被覆盖的点可能不连续。但能被覆盖的点的斜率可以保证从右至左单调递减。

若想为点集连续,可能会导致 “\(p\)\(r\) 点当前能够覆盖的最远点” 的错误贪心思路。喜提20pt。

如图,\(r=G\) 时,\(p=\{E,D,B\}\)

接下来是这题个人认为比较难处理的地方。

由于 \(p\) 不一定连续,故 \([p_{i+1}+1,p_i-1]\) 对于 \(r\) 不可见。

由上述性质得,对于 \(j\in[p_i,r)\)\(j=p_i\) 是唯一可以覆盖 \([p_{i+1}+1,p_i-1]\) 中至少一个点的点。 即在区间 \((p_{i+1},p_i)\) 右侧唯一能够覆盖到此区间的点为 \(p_i\)。(有点绕,建议自己手玩一下。)

如图,以 \(A\) 为右端点,\([D,A]\) 中能覆盖 \([G,E]\) 的唯一点为 \(D\)

当然,也可以选择在 \(p_i-1\) 处放置保镖,从内部将点覆盖。

如在点 \(E\) 放置保镖。

\(p_i,p_i-1\) 至少有一处要放置保镖。

这样就成功的将区间 \([p_{i+1}+1,p_i]\)\([p_{i+1}+1,p_i-1]\) 转换为了一个子问题。

区间 \([p_{k+1}+1,p_k-1]\) 的代价即为

\[f_{p_{i+1}+1,p_i-1}=\min\{f_{p_{i+1}+1,p_i-1},f_{p_{i+1}+1,p_i}\} \]

此时有转移方程:

\[f_{l,r}=\sum\limits_{i=1}^m\min\{f_{p_{i+1}+1,p_i-1},f_{p_{i+1}+1,p_i}\} \]

时间复杂度 \(O(n^3)\),能拿 \(70\) pts。

考虑优化。

  • 因为 \(p_i\) 是在 \([p_i,r)\) 中与 \(r\) 点连线斜率最小的,所以对于 \(x\in[l,p_i)\),若存在 \(f_{x,r}<f_{p_i,r}\),则 \(p_{i+1}=x\) 可以考虑将 \(p_i\) 在循环里滚动处理。

  • 可以注意到根据上述转移,当处理至 \(p\) 点时,区间 \([p,r]\) 可以保证被完全覆盖。有转移方程

    \[f_{l,r}=\min\{f_{l,p-1,f_{l,p}}\}+f_{p+1,r} \]

干掉一个线性时间复杂度。时间复杂度 \(O(n^2)\)

T4. 有味道的数字

题目传送门

先写一个暴搜。发现 \(n\leq 5000\) 的时候,\(|P|\leq 11\)

\(n\leq 5000\) 的所有数字可以用 \(11451419191\) 表示。

这题主要是状态设计难想。

\(f_{l,r}\) 为区间 \([l,r]\) 能表示的所有数的集合

\(A=\{1,1,4,5,1,4,1,9,1,9,1\}\)

初始化 \(f_{l,r}\)\(A_l\) ~ \(A_r\) 直接拼接的数字。如 \(f_{3,6}=\{4514\}\)

显然有状态转移:

\[\forall x \in f_{l,k},\ y \in f_{k+1,r},\ \{x+y,x\times y\}\in f_{l,r} \]

统计答案时,\(ans_x=\min\limits_{x\in f_{1,i}}i\)

T5. [HAOI2016] 字符合并

然鹅并没有过。但是可以口胡一下。

看到二进制,一眼状压。

\(f_{l,r,s}\) 为区间 \([l,r]\) 合并为 \(s\) 获得的最大累计分数。

毕竟你得满足无后效性对吧。当区间内有多种情况或多条限制时,可以考虑加维转移。

那么对于每个状态 \(s\),可以枚举断点 \(i\) 使得

\[f_{l,r,s}=\max\limits_{i=l}^{r-1}(f_{l,i,\lfloor\frac s 2\rfloor} + f_{i+1,r,s\bmod2}) \]

显然复杂度 \(O(2^{k-1}n^3)\) 会爆炸。

显然对于区间 \([l,r]\),最终合并长度为

\[L=\begin{cases}1&k-1\ |\ len-1\\(len-1)\bmod(k-1)+1&\tt otherwise\end{cases} \]

所以只需要枚举 $k-1\ |i\ $ 的情况。

从合并后的串来转移。有转移方程

\[\begin{matrix}f_{l,r,2s}=\max(f_{l,i,s}+f_{i+1,r,0})\\f_{l,r,2s+1}=\max(f_{l,i,s}+f_{i+1,r,1})\end{matrix} \]

\(L=1\) 时,可以直接合并。

时间复杂度 \(O(\frac n k\times2^{k-1}n^2)\)


个人认为区间 dp 是 dp 专题里面最简单的了。

主打一个感性理解和经验积累。真没啥套路。

想得出来就好写,想不出来就开摆。

最短路

应 Zikme 要求,不放代码。好像更抽象了

茅坑顿开。

0. 前言

下文中:

  • \(u \to v\) 表示从 \(u\)\(v\) 的单向边,\(w_{u,v}\)\(u \to v\) 的边权。
  • \(P(u,v)\) 表示 \(u\)\(v\) 的最短路径。
  • \(s\) 为源点,\(t\) 为终点。
  • \(d_u\)\(s\)\(u\) 的最短路长度。(算法执行中)
  • \(D_u\)\(s\)\(u\) 的最终最短路长度。

越简单的算法,证明越难想。——Zikme

1. dijkstra

1. 流程简述

算法核心是将图分为两个点集 \(S,\ T\)。其中 \(S\) 为已确定最短路点集,\(T\) 为未确定最短路点集。

算法流程:

重复以下操作,直至 \(T=\emptyset\)

  1. \(T\) 中选取最短路长度最小的点 \(v\)。令 \(u\)\(S\) 中存在 \(u \to v\) 的点中最短路长度最小的点。

  2. 进行松弛操作:\(d_v=\min\{d_v,d_u+w_{u,v}\}\)

  3. \(v\)\(T\) 移至 \(S\)\(D_v=d_v\)


2. 算法证明

显然,最短路有一个性质:对于一个最短路径,其前缀仍然是最短路。

故一定存在上述 \(u\) 点。

所以,只要证明加入 \(T\) 集合时 \(v\) 点的最短路已被确定(即 \(v\) 加入 \(S\)\(D_v=d_v\),dijkstra 算法得证。

考虑用反证法证明。

注:该证明只适用于边权非负的情况。这便是为什么 dijkstra 不能跑负权图。

\(u\) 为移动至 \(S\) 集合时 \(D_u<d_u\) 的点。

当前最短路径与实际最短路径至少存在一个点不相同。

\(v_1,v_2\) 为当前最短路径与实际最短路径第一个不相同的点。

\(s\)\(u\) 的当前最短路径为 \(p_1:s \to \cdots \to v_1 \to \cdots \to u\)\(s\)\(u\) 的实际最短路径为 \(p_2:s \to \cdots \to v_2 \to \cdots \to u\)

可将其简化为 \(p_1:s \to v_1 \to u,\ p_2:s\to v_2\to u\)

显然,\(v_2\) 还未被更新到的时候,\(p_1\) 才能成为最短路径。

所以有 \(v_2\in T\)

又因为 \(v_2\in p_2\) 且在 \(u\) 前,所以一定有 \(d_{v_2}<d_u\)。(注:只有在边权非负的情况下才成立。

与 “\(d_u\) 为所有 \(p\in T\)\(d_p\) 最小” 矛盾。故不存在 \(v_2\) 使得 \(p_1\) 不为最短路径。

dijkstra 算法得证。

3. 时间复杂度

暴力时间复杂度:

  • 查找 \(T\) 集合中 \(d_u\) 的最小值,时间复杂度 \(O(n)\)
  • 松弛一条边,时间复杂度 \(O(1)\)

对于图中 \(n\) 个点进行上述操作,总时间复杂度 \(O(n\times(n+1))=O(n^2)\)

优化:

由于要查找 \(T\) 集合中 \(d_u\) 的最小值,可以使用支持修改的最值数据结构。

可选的有:

  • 堆:每松弛一条边 \(u\to v\), 将 \(v\) 插入堆或修改 \(v\) 的权值,共 \(m\) 次;同时需取 \(n\) 次堆顶。时间复杂度 \(O((n+m)\log n)=O(m\log n)\)

  • 优先队列:由于优先队列不支持直接修改,故队列中有 \(m\) 个元素。总时间复杂度 \(O(m\log m)\)

哪个正经人线段树

但是当数据为稠密图 (\(m\approx n^2\)) 时,上述优化时间复杂度均退化为 \(O(n^2\log n)\) 级别。还不如暴力

2. Bellman-Ford / SPFA 证明

1. 流程简述

其本质为松弛操作:\(d_u=\min\{d_u,d_v+w_{u,v}\}\)

对图上的每一条边尝试松弛,共松弛 \(m\) 次。

意义显然。

其核心为:对于 \(P(u,v)\), 经过 \(n\) 次松弛即可保证正确性。

2. 算法证明

证明如下:

一次松弛至少可以将最短路的长度加 \(1\)

由于最短路径不可能重复经过一条边(无负权环),最坏情况(最短路为链状)需要将 \(n\) 个点全部遍历。故 \(|P(u,v)|<n\)

所以至多经过 \(n\) 次松弛操作即可保证正确性。得证。

综上所述,总时间复杂度为 \(O(n\times m)\)

3. 算法优化

显然,大多数的松弛操作都是无效的。

而只有上一次被松弛过的节点(可能在最短路径中)所连接的边才可能会有有效的松弛操作。

考虑用队列维护。反正最坏情况下复杂度也为 \(O(n\times m)\)

复杂度证明:

看不懂。不写了。反正非负权用 nm (指时间复杂度 \(O(n\times m)\)) 的 spfa。

至于怎么让这玩意死透,@changwenxuan 已经进行了详尽的研究。

干点正事。

3. Floyd 证明

1. 流程简述

\(g_{u,v}\)\(u\to v\) 的最短路。

有转移方程 \(g_{u,v}=\min\{g_{u,v},g_{u,k}+g_{k,v}\}\)

2. 算法证明

其原始方程为 \(g_{k,u,v}=\min\{g_{k-1,u,v},g_{k-1,u,k}+g_{k-1,k,v}\}\),表示只经过前 \(k\) 个点,\(u\to v\) 的最短路。

时间复杂度 \(O(n^3)\),空间复杂度 \(O(n^2)\)

试证明第一维可以直接省略。

显然有 \(f_{k-1,u,v}=f_{k,u,v}\)如果没有,图上就有负环。最短路什么的也无所谓了。

故可以将第一维直接省略。

4. Common Tricks

1. 最短路树

由于最短路的前缀也一定是最短路,所以对于单源最短路,其构成一棵有根叶向树。

主要用处是统计方案数和 dp。

2. 虚点

对于某些具有相同性质的点,可以另建一个点并将其与具有相同性质的点连边。

相当于将具有相同性质的点缩为一个点集,大幅减少边数及点数。

3. 分层图

运用 dp 思想,将不同决策导致状态不同的点装进不同的图内。

虽然一般来说这样的决策只能有一个。不然边数爆炸。

在大多数情况下等价于直接在图上进行多维 dp。

虽然我觉得建图要好看一些。

例题大赏

题目不按任何顺序排序。

[SDOI2010] 大陆争霸

第一眼看上去好像是最短路加了个强制拓扑。

也就是说当结界还没被破坏的时候,已经到达的机器人只能干等着。

在 dijkstra 中,机器人所在的点可以更新最短路。但拓扑图上该点的入度不为 \(0\),即结界产生器没有被全部破坏时,不能入队。

当炸掉一个结界产生器的时候,可以将其在拓扑图上连接的所有点的入度减一。

而当拓扑图上的一个点入度为 \(0\),即结界产生器全部被破坏的时候,便可以入队。

不用考虑当前是否有机器人在该点等待。即使没有,由于题目保证有解,所以若该点在 \(1\to n\) 的最短路上一定可达。之后也会有更优决策来替代它。

爆改 dijkstra。需要对算法流程有一定的理解。

CF1648E

题目传送门

在一带权无向图上,每次只能连续经过两条边,且代价为两条边边权之和的平方。求单源最短路。

数据范围 \(1\leq n\leq10^5,\ 1\leq m \leq 2\times10^5,\ 1\leq w\leq50\)

暴力建图的话总边数为 \(m^2\),会爆炸。

考虑一个路径 \(u\to x\to v\)\(w_1=w_{u,x},\ w_2=w_{x,v}\)

由于一次移动至少要经过两条边,所以上述代价和等价于将边权全部移到 \(x\to v\) 上。

这样的话 \(u\to x\) 就没那么重要了。在 \(w_2\) 一定的情况下共有 \(w=50\) 种可能的权值。

可以考虑以 \(w_1\) 的值构造分层图。

\((w,u)\) 为入边边权为 \(w\) 且入点为 \(u\)点集。但是由于其并不影响最终结果,可以将其作为一个点。

则对于点对 \((u,x,v)\),可以将 \(u\)\((w_1,u)\) 连一条边权为 \(0\) 的边;将 \((w_1,u)\)\(v\) 连一条边权为 \((w_1+w_2)^2\) 的边。

显然 \(u\to v\) 的代价等价于原图。

显然,对于一个点 \(u\)(假定其为路径的起始点),分层后其最大出度为 \(w=50\)

总边数从 \(m^2\) 骤降到了 \(mw\)

总时间复杂度为 \(O(m\log m)\) 左右。

分层图的各种妙妙玩法。

没思路时可以考虑转移边权或点权。

例如缩点,点权转边权等。

[HAOI2010] 道路

题目传送门

不管怎么说,双倍经验


题意很简洁了。

对于每个源点 \(s\),先跑一遍 dijkstra。显然,若满足 \(dis_v=dis_u+w_{u,v}\),则 \(e(u,v)\) 一定在最短路上。

显然在 \(w_{u,v}>0\) 时,不存在 \(u,v\) 使得 \(dis_u=dis_v+w_{u,v} \wedge dis_v=dis_u+w_{u,v}\)

因此,若将最短路径上的点从原图中取出,加入集合 \(V\),其构成的图一定为 DAG \(G(V,E)\)

可以考虑将其进行拓扑排序。

其实是可以在 dijkstra 中排序的。dijkstra 的遍历顺序就是拓扑序。但是如果你硬要再写一遍也没人拦你

然后捏?

图上 dp。

\(G(V,E)\) 的源点(集)为 \(s'\),汇点(集)为 \(t'\)

对于任意 \(E_i=e(u,v)\),设 \(out_i\)\(s'\to u\) 的方案数,\(in_i\)\(v\to t'\) 的方案数。

根据乘法原理,得 \(ans_i=in_i\times out_i\)

\(out_i\) 好求。转移方程为 \(out_u=out_u+out_v[dis_u+w_{u,v}=dis_v]\ \ e(u,v)\in E\)

事实上 \(in_i\)\(out_i\) 的求法是一样的。

\(v\to t'\) 这部分建个反图 \(G'(V',E')\) 就可以达到同样的效果。

转移方程为 \(in_u=in_u+in_v[dis_v+w_{u,v}=dis_u]\ \ e(u,v)\in E'\)

在 DAG 上算方案数有两种基本策略:

  • 按照拓扑序 dp。
  • 对于每个点 / 边分类讨论后,运用组合数学求方案数。

[NOIP2017] 逛公园

看到 \(k=50\),考虑按路径长度为一维度 dp。

\(f_{u,k}\) 为 从 \(1\)\(u\) 路径长度为 \(d_u+k\) 的总方案数。

需要以倒拓扑序的顺序进行转移。

对于图上的每条边 \(e(u,v)\),有转移方程:

\(f_{u,k}=\sum\limits_{e(u,v)}f_{v,k-(d_u + w - d_v)} \ (d_u+w-d_v<k)\)

其中 \(d_u+w_{u,v}-d_v\) 为较 \(d_v\) 经过 \(e(u,v)\) 多走的路程。

考虑按路径长度进行记忆化搜索求解。

具体实现可以建反图后搜索。

注:在搜索过程中如果遇见 \(0\) 环,则存在无穷种路径,输出 \(-1\)。可以通过维护每个点在当前路径长度被搜索到的次数判环。

若题目对某一条件存在限制,可以考虑将条件列入 dp 方程中求解。

[GZOI / GXOI2019] 旅行者

如果已知分组方案,对两组分别建立虚拟原点后跑最短路即可。

主要问题是如何分组。

随机化算法 shuffle 战神

设答案源点为 \(u\),汇点为 \(v\)

\(K\) 分为大小相同的两组 \(K_1,K_2\)\(u\in K_1\wedge v\in K_2\) 的概率为 \(\frac 1 4\)

故尝试 \(T\) 次全错的概率为 \(1-(\frac 3 4)^T\)

尝试 \(20\) 次左右就行了。正确率为 \(99.68\%\)

upd: NKOJ过不了。

二进制分组

按照 \(K_i\) 二进制上的每一位分组。

正确性证明:

显然源点与汇点是不同的点。故其至少有一个二进制位不同。将其按每一位的二进制分组,至少有一次源汇点会被分在不同组。

upd: NKOJ也过不了。

upd2: 没判 -1 导致的。

时间复杂度 \(O(m\log^2n)\)

果国的奇妙旅行

题目传送门

下文中令 \(d_u\) 为点 \(u\) 的度数。

如题,求最优策略下的期望购票数。

期望:若有连续随机变量 \(x\),其期望 \(\mu_x=\sum\limits_{x\in D}x\times p_x\)

其中 \(D\) 为定义域,\(p_x\)\(x\) 出现的概率。

由于结果确定,通常期望 dp 采用倒推的方式。

\(f_u\)\(u\)\(n\) 的期望购票数。

将决策分开考虑。对于每个在点 \(u\) 抽到了去点 \(v\) 的票,有两种决策:移至 \(v\) 点或留在原地。

这样的状态设计可以让实际决策形成一个 DAG。

显然,若有 \(f_v\geq f_u\),最优决策为留在原地,期望为 \(\frac {f_u}{d_u}+1\)

反之则可以移至点 \(v\),期望为 \(\frac {f_v} {d_u}+1\)

故有转移方程

\[\forall e(u,v):f_u=1+\frac1{d_u}(\sum\limits_{f_u\leq f_v}f_u+\sum\limits_{f_u>f_v}f_v) \]

写起来挺好看的。但是在 \(f_u\) 的递推式中出现了自己。那就不好玩了。

不能用正常顺序求解。

注意到一个性质:\(\forall e(u,v):\min f_u\) 一定是由 \(\min f_v\) 转移过来的。

感觉和 dijkstra 有点像。考虑在 dijkstra 的过程中维护 \(f_u\)

可以考虑把 \(f_u\) 替换成其他的可维护变量。

然后发现好像 \(f_u>f_v\) 的数量是可以维护的。顺便把 \(\sum\limits_{f_u>f_v}f_v\) 的值维护了。

每次选出当前已知的最小 \(f_v\)。对于每条边 \(e(u,v)\), 令 \(l_u\) 为满足 \(f_u>f_v\) 的数量,\(s_u\) 为满足 \(f_u>f_v\)\(f_v\) 总和。

将上述方程化简得:

\[f_ud_u=d_u+(d_u-l_u)f_u+s_u \]

解得:

\[\begin{matrix}f_u=\frac{s_u+d_u}{l_u}&(f_u>f_v)\end{matrix} \]

注:可以将 \(f_u\) 初始化为 \(\infin\)。~~如果后面有解的话,这反正也不是最优解。和 \(dis_u=\infin\) 一个意思。

优雅。这样就将 \(f_u\) 这个无法维护的量转为了 \(d_u\)\(l_u\)\(s_u\) 三个可以维护的量。

图上期望 dp 的思路为:

  • 确定最优策略
  • 倒序 dp
  • 若方程存在自环,可以将方程拆开后根据可维护变量进行转移。

[NKOJ8736] 指针分析

我也不知道这玩意为什么要放到最短路专题里。

将字母压位后 模 拟 即 可。

posted @   CQWDX  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示