DP做题记录

写在前面

DP能力几乎已经退化到 \(0\)

部分题目是从同机房某神仙的提交记录里爬来的

线性DP

CF414B Mashmokh and ACM

题目传送

Solution:

\(f_{i, j}\) 表示选了第 \(i\) 个数,当前最大的数位 \(j\)
显然有转移方程 \(f_{i, j} = f_{i - 1, k}\) ,其中 \(k\)\(j\) 的因数
可以通过枚举 \(k\) 的倍数的方式来优化

Code

P1280 尼克的任务

题目传送

Solution

\(f_i\) 表示 \([i,n]\) 这段时间中的最长休息时间
如果当前没有工作,那么 \(f_{i} = f_{i + 1} + 1\)
否则,他必须选一个工作,\(f_{i} = \max\{f_{i + a[j].ed}\}\),其中 \(j\) 是每项起始时间在 \(i\) 的工作

Code

P5957 [POI2017]Flappy Bird

题目传送

Solution

直接在两个柱子间转移。

维护一个能到达的区间,到达下一个柱子会有一个能到达的最大值和最小值

然后和下一个柱子的区间取并即可。

发现坐标和一定是一个偶数,判断一下所在位置不合法的情况在稍微改变一下就行。

最后的答案?设点了 \(x\) 下,最终在 \((a,b)\) 处,有

\[x = \frac{a+b}{2} \]

Code

CF618D Hamiltonian Spanning Tree

题目传送

Solution

特判几个特殊情况。

然后用 路径中的点的度为2 去用 dfs 贪心,跑出最多选出的树边。

Code

根据 Chen_怡 的代码自己yy了一道魔改),正解就是这份代码中的dfs函数

P4095 [HEOI2013]Eden 的新背包问题

题目传送

询问很多,考虑把所有情况预处理出来。吸氧之后有 \(80pts\) 的好成绩。

\(f_{i,j}\),表示到第 \(i\) 个物品,用了 \(j\) 的容量。
从前面跑一边从后面跑一边预处理出来。
当询问第 \(x\) 个不能选时,就相当于把所有物品分成 \([1,x-1]\)\([x+1,n]\) 两份。枚举分给两份的容量,然后在找出最大值就是答案。

附一句:这样做的极限复杂度是 \(3 \times 10^8\),实际情况要快的多,大概是数据水?

Code

CF864E Fire

题目传送

普通的 01背包 变形,不用多想。
先对背包容量 \(d\) 排个序,然后照着跑就行了
选的方案可以直接用 \(\text{vector}\)

注意最大的时间对应的答案不一定是最优的

P1450 [HAOI2008]硬币购物

容斥原理?
先跑个多重背包统计方案。令答案为 \(f_{s}\)

考虑只有一种硬币的情况
假设 \(c_i\) 限制数量 \(d_i\),为了排除数量超出的干扰,可以在原来的基础上减去 \(f_{s - (c_i * (d_i + 1))}\)

多枚硬币用类似的思想进行容斥就好了

P3188 [HNOI2007]梦幻岛宝珠

\(f_{i, j}\) 表示对于 \(b\)\(i\) 的物品进行背包,当容量为 \(j\) 的时候的最大价值。

然后我们再设一个数组 \(g[i][j]\) 表示当使用 \(b\)\(0\sim i\) 的物品进行背包,\(b\)\(i\) 的物品所占空间为 \(j\) 时,剩余物品(即 \(b\)\(1\sim i-1\))所占空间为 \(m\&((1<<i)-1)\) 的最大价值。

而这个 \(m\&((1<<i)-1)\) 简单来说就是 \(m\)\(i\) 位以下的值。

接着我们就可以考虑转移了,转移方程式如下:

\[g[i][j]=\max(g[i][j],f[i][j-k]+g[i-1][min(10\times n,k\times2+(m>>(i-1))\&1)] \]

那这个方程是什么意思呢??

我们可以这样想,我们从 \(j\) 中拆除 \(k\),拿给剩下的物品放。而高位向低位转移时会 \(\times 2\),然后再加上 \(m\) 中该位上的值 \((m>>(i-1))\&1\) 表示 \(m\)\(i-1\) 位上的值)

最后我们只需要输出 \(g[m 的位数][1]\) 就可以了(因为 \(m\) 的首位一定是 \(1\)

posted @ 2021-04-29 10:59  Suzt_ilymtics  阅读(76)  评论(2编辑  收藏  举报