loading...

动态规划复习

The Maximum Prefix *3200

你需要生成一个长度不超过 \(n\) 的数组 \(a\),其中每个 \(a_{i}\) 的取值为 \(1\)\(-1\)

你按照如下方式生成该数组:

  • 首先,你选择一个整数 \(k\)\(1\le k \le n\)),决定数组 \(a\) 的长度。
  • 然后,对于每个 \(i\)\(1\le i \le k\)),你以概率 \(p_{i}\)\(a_{i} = 1\),否则以概率 \(1 - p_{i}\)\(a_{i} = -1\)

数组生成后,你计算 \(s_{i} = a_{1} + a_{2} + a_{3}+ \ldots + a_{i}\),特别地,\(s_{0} = 0\)。然后令 \(S = \displaystyle \max_{i=0}^{k}{s_{i}}\),即 \(S\) 是数组 \(a\) 的最大前缀和。

你会得到 \(n+1\) 个整数 \(h_{0}, h_{1}, \ldots, h_{n}\)。对于最大前缀和为 \(S\) 的数组 \(a\),其得分为 \(h_{S}\)。现在,对于每个 \(k\),你需要求出长度为 \(k\) 的数组的期望得分,对 \(10^9+7\) 取模。\(n \le 5000\)

注意经典题。

前缀和如果正向做不容易同时维护 \(S\) 和当前前缀和。注意倒着做,定义 \(f_{i,j}\) 表示确定了 \(i \sim k\) 的值,当前最大前缀和为 \(j\) 的概率。注意在开头加一个数,容易发现 \(S=j \to S=\max\{0,j \pm 1\}\),因为前缀和会整体都 \(\pm 1\),再在前面加一个 \(0\)

\[f_{i,j}(1-p_{i-1}) \to f_{i-1,\max\{j-1,0\}}\\ f_{i,j}p_{i-1} \to f_{i-1, j+1} \]

但是注意,这里隐含了 \(k\)\(\mathcal O(n)\) 枚举,总复杂度 \(O(n^3)\),因此,注意这个 dp 是多个起点单个终点,需要改变 dp 方向。

倒过来就好了。考虑 dp 意义,\(g_{i,j}\) 表示确定 \(1 \sim i\) 的值,当前离我期望达到的最大前缀和 \(S\) 还需后面的 \([i+1,k]\) 这一部分最大前缀和为 \(j\) 才可以,得分的期望值。

\[\begin{aligned} g_{i-1,\max\{j-1,0\}}p_i &\to g_{i,j}\\ g_{i-1,j+1}p_i &\to g_{i,j} \end{aligned} \]

First Come First Serve *2697

\(N\) 位顾客会光顾某家店,我们将他们编号为 \(1,\ldots,N\)。第 \(i\) 位顾客在时刻 \(A_i\) 进入店内,在时刻 \(B_i\) 离开店铺。该店的排队方式为“先进先出”,即 \(A_i\)\(B_i\) 都是严格递增的。此外,所有的 \(A_i\)\(B_i\) 互不相同。

在店门口有一份顾客可以签名的名单。每位顾客仅能在入店时或离店时,将自己的名字写在名单的末尾一次。请问,最终名单上名字的可能排列方式有多少种?请将答案对 \(998\,244\,353\) 取模后输出。\(N\le 5 \cdot 10^5\)

一种签名方式的选择序列:如 \(abaa...\),第 \(i\) 为表示顾客是选择 \(A_i\) 还是 \(B_i\) 时签名。选择序列每个人只有 \(2\) 个选择,考虑从这个角度计数。

一个名字排列所对应多种选择序列,所以套路性的,考虑代表元,容斥掉非代表元的部分。

令代表元为:对应同一名字排列中选择序列尽量多选 \(A_i\) 的那一个。

  • 选择 \(a_i\),系数为 \(1\)
  • 选择 \(b_i\),不考虑其他情况,系数为 \(1\)
  • 选择 \(b_i\),但 \(a_i \sim b_i\) 这一段无人签名,系数为 \(-1\)

定义 \(f_i\) 为决策完 \(1 \sim i\) 位的状态,方案的系数积之和。

\[f_i \gets f_i+2f_{i-1}\\ \forall i:f_p\gets f_p-f_q \]

其中 \(i\) 是对应第三种情况的 \(i\)\(q=\max\{j|j<i \land b_j<a_i\},p=\min\{j|j>i\land b_i<a_j\}\),直接维护就可以做到 \(\mathcal O(n)\) 了。

Bow Meow Optimization

\(N\) 只编号为 \(1\)\(N\) 的狗,以及 \(M\) 只编号为 \(1\)\(M\) 的猫。现在要将这 \(N+M\) 只动物以任意顺序排成一排。根据排列的方式,每只狗和猫会产生如下的“不满度”:

  • 对于第 \(i\) 只狗,设在它左边的猫有 \(x\) 只,右边的猫有 \(y\) 只,则它的不满度为 \(A_i\times|x-y|\)
  • 对于第 \(i\) 只猫,设在它左边的狗有 \(x\) 只,右边的狗有 \(y\) 只,则它的不满度为 \(B_i\times|x-y|\)

请你求出所有动物不满度总和的最小值。

  • \(1\leq N, M \leq 300\)
  • \(1\leq A_i, B_i \leq 10^9\)
  • 输入均为整数

性质是前 \(\lfloor\frac{m}{2}\rfloor+\lfloor\frac{n}{2}\rfloor\) 中一定有 \(\lfloor\frac{m}{2}\rfloor\) 只猫和 \(\lfloor\frac{n}{2}\rfloor\) 只狗。

将左边多余的猫与右边多余的狗交换调整即可得证。

将序列划分为 \(k\) 段,每段的价值为 \((A_l-A_r)^2\),求价值和的最小值。

\(A_i \le 10^6,n \le 10^4,k \le 100\)

\[\begin{aligned} f_{i,j}&=\min _{k < i}\{f_{k,j-1}+A_{k+1}^2+A_i^2-2A_{k+1}A_{i}\}\\ &=\min_{k<i}\{f_{k,j-1}+A_{k+1}^2-2A_{k+1}A_i\}+A_i^2 \end{aligned} \]

李超线段树维护即可做到 \(kn \log n\) 的复杂度。

斜率优化

注意李超线段树是直观的竖线找最高/低交点,但斜率优化最常见的写法并非如此:

若方程 \(f_{i}=\min_{j <i} \{a_{j}+c_jd_i\}+e_i\),斜率优化是将其看做:

前有若干点 \((x_j,y_j)\),用斜率 \(d_i\) 去过那个点的直线的最小截距。

对于直线 \(y=kx+b\),这里逐一替换得到:\(y_j=d_ix_j+b\) 移项:\(y_j-d_ix_j=b\)

容易得到 \(x_j=-c_j,y_j=a_j\),方程式写作:\(f_{i}=b+e_i\),。

然后若斜率 \(d\),横坐标 \(x\) 分别单调,那么可以维护一个下凸壳做到 \(\mathcal O(n)\) 斜优。

Yet Another Partition Problem *3000

给定数组 \(a_1,a_2 ⋯a_n\),你需要将它划分成 \(k\) 段(每个元素在且仅在一段中),某段 \(a_l,a_{l+1} ⋯a_r\) 的权值为 \((r−l+1) \times \max\limits_{i=l}^r{a_i}\),整个划分的权值是每段权值之和。求最小划分权值。

\(n \le 2×10^4 ,k \le 100\)

定义暴力 dp,\(f_{i,j}\) 表示将 \([1, j]\) 划分为 \(i\) 段的最小代价。

转移:

\[f_{i,j}=\min_{k<j}\{f_{i-1,k}+c(k+1,j)\} \]

观察代价函数 \(c(l,r)=(r-l+1)\displaystyle\max_{l\le i \le r} a_i\),发现 \(\max\) 并不是一个友好的东西。

单独考虑每一层转移,即 \(f_{i-1} \to f_i\)

考虑分治,处理 \([l,m]\)\([m+1,r]\) 的转移,然后递归处理内部转移。

想想这样有什么好处,分治后从 \(m\) 两边开始可以 \(\mathcal O(n)\) (每层而言)处理出 \(\max\),然后将 \(\displaystyle\max_{l \le i \le r}\) 拆成 \(l \le i \le m\) 一段和 \(m < i \le r\) 一段的 \(\max\)。令 \(lm_i\) 为左边的后缀 \(\max\)\(rm_i\) 为右边的前缀 \(\max\)

然后就可以将转移写作:

\[f_{i,j} \gets \min\{f_{i-1,k}+(j-k)\max\{lm_{k+1},rm_j\}\} \]

这样就比较方便分讨:

  • \(lm_{k+1} \le rm_{j}\):转化为斜优形式就是:

    \[f_{i,j} \gets \min \{f_{i-1,k}-k\times rm_{j}\}+j \times rm_j \]

  • \(lm_{k+1} > rm_{j}\):转化为斜优形式就是:

    \[f_{i,j} \gets \min \{(f_{i-1,k}-k\times lm_{k+1})+j\times lm_{k+1}\} \]

两者均可以使用斜率优化,所以只需考虑将 \(lm_{k+1}\)\(rm_{j}\) 大小关系放到 dp 中,双指针即可。

posted @ 2026-01-15 16:40  goldspade  阅读(0)  评论(0)    收藏  举报