动态规划习题

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

I CF53E Dead Ends

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

fnow{j},p{i}{j}fnow,p

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

代码

II P5369 [PKUSC2018] 最大前缀和

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

  • 对于 j<ij1,需满足 k=ji0,即 i 之前的数列的后缀和不小于 0,总和除外。
  • 对于 j>i,需要满足 k=ij<0,即 i 之后的数列的前缀和小于 0

n 较小,考虑状压,设 fnow 表示所有前缀和 <0 的方案数,gnow 表示所有后缀和 0 的方案数,有:

  • fnow{i}fnow    ,inow,snow{i}<0
  • gnow{i}gnow    ,inow,snow{i}0

其中 snow 表示 now 状态中所有节点权值和。

由于前缀总和的和不需要 <0,所以我们在 DP 中直接计算答案,有:ansfnow×gallnow{i}×snow{i}all 表示全集,即 (1<<n)1

复杂度 O(2nn)

代码

III AT_arc107_d Number of Multisets

fi,j 表示 i 个元素,和为 j 的方案数。

若为 1fi,jfi1,j1,否则可能成为分数,考虑由其他状态转移。

若为 12,则可以由 fi1,2j1 转移,也就是将该状态的数都 2,这样再加上 12 即为 j

其余同理,类似前缀和的我们可以倒序枚举,有 fi,jfi,2j

复杂度 O(n2)

代码

IV P3643 [APIO2016] 划艇

好题。

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

fi,j 表示前 i 个学校,当前学校选择 [cj,cj+1) 中的数的方案数,因为有可能前 i1 个点也在该区间,所以我们先求若还有 k 个点选择 j 区间,插板法易得方案数为 (cjcj+1+kk+1),所以我们可以枚举不在区间 j 的点。

若区间 i 包含 j 区间,fi,j=k=1i1l=1j1fk,j×(cjcj+1+kk+1)

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

对于 l=1j1fk,j,其与后面的组合数没有关系,可以前缀和处理。

复杂度 O(n3),记得预处理逆元,不要像我这个傻逼多写的 log 都不知道

代码

V Random IS

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

我们考虑区间 DP,设 fi,j,表示钦定选定 ai,aj 在区间 (l,r) 内选择的期望。

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

所以有转移 fi,j=1+1cntk=i+1j1fi,k+fj,k[ai<ak<aj],cnt=k=i+1j1[ai<ak<aj],直接转移是 O(n3)

用数据结构维护下,可以达到 O(n2logn),可以用 值域BIT。

代码

posted @   oXUo  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
网站统计
点击右上角即可分享
微信分享提示