动态规划习题

动态规划需要大量的练习,运用所学习的技巧优化,本篇为练习。

I CF53E Dead Ends

\(n\) 很小,考虑状压,\(now\) 状态是一定要有的,每加一条边我们叶子节点会变化,这启示我们记录叶子结点的集合 \(p\),设 \(f_{now,p}\) 表示 \(now\) 状态下,该树叶子结点状态为 \(p\) 的方案数,则对于一条边 \((i,j),i \in now,j \notin now\),有

\[\large f_{now \cup \{j\},p \setminus \{i\} \cup \{j\}} \gets f_{now,p} \]

对于每个状态可能会有多算的,需要除上 \(|p|\),初始化两个节点的情况,复杂度 \(\mathcal{O}(3^nn^2)\)

代码

II P5369 [PKUSC2018] 最大前缀和

我们有数列 \(a\),对于 \(i\) 其是最大前缀和,则需要满足的条件:

  • 对于 \(j < i,j \not= 1\),需满足 \(\sum\limits_{k=j}^i \geq 0\),即 \(i\) 之前的数列的后缀和不小于 \(0\),总和除外。
  • 对于 \(j > i\),需要满足 \(\sum\limits_{k=i}^j < 0\),即 \(i\) 之后的数列的前缀和小于 \(0\)

\(n\) 较小,考虑状压,设 \(f_{now}\) 表示所有前缀和 \(< 0\) 的方案数,\(g_{now}\) 表示所有后缀和 \(\geq 0\) 的方案数,有:

  • \(f_{now \cup \{i\} } \gets f_{now} \ \ \ \ , {i \notin now,s_{now \cup \{i\}} < 0}\)
  • \(g_{now \cup \{i\} } \gets g_{now} \ \ \ \ ,{i \notin now,s_{now \cup \{i\}} \geq 0}\)

其中 \(s_{now}\) 表示 \(now\) 状态中所有节点权值和。

由于前缀总和的和不需要 \(< 0\),所以我们在 DP 中直接计算答案,有:\(ans \gets f_{now} \times g_{all \setminus now \setminus \{i\}} \times s_{now \cup \{i\} }\)\(all\) 表示全集,即 \((1 << n) - 1\)

复杂度 \(\mathcal{O}(2^nn)\)

代码

III AT_arc107_d Number of Multisets

\(f_{i,j}\) 表示 \(i\) 个元素,和为 \(j\) 的方案数。

若为 \(1\)\(f_{i,j} \gets f_{i-1,j-1}\),否则可能成为分数,考虑由其他状态转移。

若为 \(\frac 1 2\),则可以由 \(f_{i-1,2j-1}\) 转移,也就是将该状态的数都 \(2\),这样再加上 \(\frac 1 2\) 即为 \(j\)

其余同理,类似前缀和的我们可以倒序枚举,有 \(f_{i,j} \gets f_{i,2j}\)

复杂度 \(\mathcal{O}(n^2)\)

代码

IV P3643 [APIO2016] 划艇

好题。

首先可以离散化,对于 \(i\),表示选择区间 \([c_i,c_{i+1})\) 中的划艇个数,利用左闭右开区间可以更好处理。

\(f_{i,j}\) 表示前 \(i\) 个学校,当前学校选择 \([c_j,c_{j+1})\) 中的数的方案数,因为有可能前 \(i-1\) 个点也在该区间,所以我们先求若还有 \(k\) 个点选择 \(j\) 区间,插板法易得方案数为 \(\dbinom {c_j - c_{j+1} + k} {k + 1}\),所以我们可以枚举不在区间 \(j\) 的点。

若区间 \(i\) 包含 \(j\) 区间,\(f_{i,j} = \displaystyle\sum_{k=1}^{i-1}\sum_{l=1}^{j-1}f_{k,j} \times \dbinom {c_j - c_{j+1} + k} {k + 1}\)

对于组合数有 \(\dbinom {n + 1} {m + 1} = \dfrac {n + 1} {m + 1}\dbinom n m\),展开易证,我们倒序枚举 \(k\),可以 \(\mathcal{O}(1)\) 处理组合数。

对于 \(\sum\limits_{l=1}^{j-1}f_{k,j}\),其与后面的组合数没有关系,可以前缀和处理。

复杂度 \(\mathcal{O}(n^3)\),记得预处理逆元,不要像我这个傻逼多写的 log 都不知道

代码

V Random IS

直接 DP,有问题,具体是因为对于相同的选择,不同的顺序是会影响其概率的。

我们考虑区间 DP,设 \(f_{i,j}\),表示钦定选定 \(a_i,a_j\) 在区间 \((l,r)\) 内选择的期望。

这里有一个奇怪的地方,为何我们不考虑区间外的点呢,可以知道因为钦定了 \(i,j\) 所以选择区间外的点是不影响区间内的可选点集的,即其影响到只是其时间先后,而不是顺序,即这些选择的顺序是不影响概率的,我们可以枚举中间节点进行转移。

所以有转移 \(f_{i,j} = 1 + \dfrac 1 {cnt}\displaystyle\sum_{k = i+1}^{j-1}f_{i,k} + f_{j,k}[a_i < a_k < a_j],cnt =\displaystyle\sum_{k = i+1}^{j-1}[a_i < a_k < a_j]\),直接转移是 \(\mathcal{O}(n^3)\)

用数据结构维护下,可以达到 \(\mathcal{O}(n^2\log{n})\),可以用 值域BIT。

代码

posted @ 2024-11-13 22:23  oXUo  阅读(6)  评论(0编辑  收藏  举报
网站统计