-
DP 题集 2
关于 DP 的一些题目
- String painter 先区间 DP,(dp[l][r]) 表示把一个空串涂成 (t[l,r]) 这个子串的最小花费。再考虑 (s) 字符串,(f[i]) 表示前 (i) 个字符相同时的最小花费。
- Parade 单调队列优化 DP。
- Free Goodies 对于第一个人,她选择的顺序是固定的。第二个人想要选到全局最优,那么有 (dp[i][j]) 表示到第 (i) 个数时,选了 (j) 个数时的最大值,顺便再记录下第一个人选的最大值。
- Help Bubu 状态压缩 DP,有 (dp[i][j][k][s]) 表示到第 (i) 本书时,拿了 (j) 个出来,最后一本书的高度为 (k) ,书的高度的状态是 (s) 的最小混乱程度,计算最终答案时,对于拿出来的书,只有状态中没有对应的高度才会造成混乱度增加。
- Caves 树形 DP ,距离值太大,但是点数很小,考虑 (dp[i][j][k]) 表示以 (i) 为根结点的子树 ,从 (i) 出发走了 (j) 个点,是否 ( (k=0 or 1) ) 回到根结点的最短距离。
- Masud Rana 状态压缩 DP ,期望 DP 。(dp[S]) ,(S) 转化成二进制后 0/1 表示某个点是否被走过,那么显然走过点都在一个联通块里,考虑下一次走到一个新的点(扩展联通块),还是仍然在联通块里,累加期望即可。
- Fund Management 状态压缩 DP 。首先,仅仅记录有哪些股票是不够的,考虑手数,不好设计状态。可以预处理状态转移,即从一种股票组合是否能通过买或卖到另一种股票组合(这样就不用管有哪些股票,有几手股票了)。
- Evacuation Plan 先分别排序,然后有 (dp[i][j]) 表示前 (i) 个人分配到前 (j) 个避难所的最小花费。滚动数组优化,记录方案可以用 bool 类型的数组。
- Exclusive Access 2 经典模型:图的色数。 给一个无向图 (G) ,把图中的结点染成尽量少的颜色,使得相邻节点颜色不同,可以用状态压缩 DP 求解。回到这题,实际上是给出一个无向图,要求给无向边定向,使其无环且最长路最短。考虑给结点分层,要求每一层的结点之间没有边,那么最小层数即为图中的最长路加1 ,对于具体的边的定向,编号小的层中的结点的向编号大的层中的结点连边。分层实际就变成了图的色数问题,过程中记录下分层的方案即可。
- Mountain Road (dp[i][j][k]) 表示最后一个走的车是 (k) 这边的,(A) 边的车走了 (i) 辆,(B) 边的车走了 (j) 辆时的最小花费。
- Interstellar Travel 利用分块的思想优化,(dp[d][i][j]) 表示 (i) 到 (j) 经过 (d) 条边的最短距离,(f[d][i][j]) 表示 (i) 到 (j) 经过 (100*d) 条边的最短距离,对于询问边数 (d),显然可以表示成 $ ( d%100, d/100) $ ,因为求的是至少 (d) 条边,所以再预处理下, (g[d][i][j]) 表示 (i) 到 (j) 的经过了至少 (d) 条边的最短距离。对于询问,枚举中间点 (k) ,$ min(f[d/100][s][k] + g[d%100][k][t]) $ 即为答案。
- Random Sequence (dp[i][j][k][p]) 表示到第 (i) 个数,(j=gcd(a[i-2], a[i-1], a[i])), (k=gcd(a[i-1],a[i])), (p=a[i]) 时对答案的贡献。实际合法的状态很少,预处理下即可。
- Hills And Valleys 预处理以某点开始或结尾的最长上升子序列长度,然后枚举要翻转的区间的值域 ([l,r]) , 在这个约束下转移,实际上我们要确定的就是某个下降的子序列的起点和终点,转移的时候记录下起点,对于每个数都判断下是否可能为终点即可。
- Shoot Game 对于每个线段,向端点射击显然最优,再就是对于一个区间中的所有线段,最大权值的线段先射击一定不坏,考虑区间 DP ,将射击指向的方向按极角排序,区间 DP 的时候,对于一段区间,只需要考虑完全包含在这个区间中的线段。
- Histogram Coloring 计数 DP ,递归实现很方便 。
- Moving to Nuremberg 树形 DP 。经典模型,统计树中所有结点到某个结点的距离,本题中,可以把每年要去某个点的次数看作这个结点的 (size)。
- Binary Strings 矩阵快速幂优化 DP 。等比矩阵求和。
- 度度熊看球赛 应该算是比较经典的 计数 DP 了。(dp[i][j]) 表示前 (2*i) 个人,有 (j) 对情侣是挨着坐的方案数,考虑新来的两个人,要么坐一起,要么分开坐,要么拆散别人,要么不拆散。预处理下即可。
- Dinner Bet 概率 DP 。(dp[i][j][k]) 表示独属于第一个人的数字已经填了 (i) 个,独属于第二个人的数字已经填了 (j) 个,两人共有的数字填了 (k) 个时的还要进行的游戏轮数的期望。记忆化搜索,暴力枚举每次选 (d) 个数字的组合,然后转移即可。在转移的时候要考虑一个对状态有影响的数字都没选到的情况,(dp = p0 * dp + p1 * dp1 + p2 * dp2 ....) 可以通过移项变换成 $ dp = frac{p1 * dp1 + p2 * dp2 + ....}{1 - p0} $ 。
- 公共子序列 考虑随机生成的数列有什么性质,相同的数必然很少,考虑经典的 LCS 是怎么转移的,只有所有序列中有相同的数字 ( 比方说 $a_i=b_j=c_k $ 我们称 ((i,j,k)) 为一个状态 ),才能从前面转移过来,预处理所有这样的状态。状态总数不会很多,几乎是 (n) 的级别,再 (O(n^2)) DP 即可。
- 棋盘上的旅行 先考虑棋盘上只有 (k) 种颜色的情况,直接状态压缩 DP ,(dp[S][x][y]) 。但是棋盘颜色很多,怎么办?不妨压缩颜色的值域,所有颜色都对应到 ([1,k]) (随机化),然后直接 DP 即可,考虑单次的正确性,(frac{k!}{k^k}) (也就是我们选到的颜色恰好是一个排列),(1000) 次可以确保通过本题。
- Pop the Balloons 状态压缩 DP 。(dp[i][S]) 表示到第 (i) 列,已经爆炸的行数状态为 (S) 的方案数。这里会有一个问题,一个气球可能被同列的气球炸到,也有可能被同行后面的气球炸到,也就是说,存在决策,某一列一个气球都不炸,这样二进制就表示不了状态了。但是考虑每行最多只会炸一次,最外层的循环,可以枚举所有必然爆炸的行的状态 (S) (也就是说,我们假定这些行一定爆炸),一行爆炸后,后面的气球再也不能引爆了,所以在状态转移的时候,到某一列,所有存在的气球的状态,只有没爆炸过的气球才会爆炸,最后的结果就是 (dp[n][S]) ,时间复杂度 (O(nm3^m))。通过暴力枚举,建立约束,优化了 DP 的状态表示。
- Fibonacci Subsequence 考虑从后往前 DP ,(dp[i][j]) 表示满足条件的序列倒数第二项是 (a[i]) ,最后一项是 (a[j]) 时的最大长度。找到 (a[k]=a[i]+a[j]) 的 (k) 来转移。
- Wrap Around 预处理 (nxt[i][j]) 表示模式串中长度为 (i) 的前缀串后面加个 (j) 后匹配到的最长前缀串的长度。(dp[i][j][k][ok]) 表示到长度 (i) 时,匹配了前缀长度为 (j) ,初始状态为 (k) ,是否出现过模式串的方案数。这里巧妙的地方在于我们枚举初始状态 (k) ,最后要回到初始状态,即当 (i=n) 时 (j=k) 以及 (ok=1) 时才得到一个合法的方案。
- Vasya and Big Integers 首先 Z-function。 (dp[i]) 表示 (s[i...n]) 可以表示出的合法的方案数。如果两个数字长度相同,那么从左到右第一位不同的数字就可以确定大小。预处理 (z[i]) 表示从 (i) 开始的字符串与原字符串的最长公共前缀长度,我们可以确定可以从哪些 (dp[j] (j>i)) 转移过来,即 (s[i..j-1]) 这个子串表示的数字在 ([l,r]) 之间,这个利用后缀和优化。
-
相关阅读:
Idea安装Scala插件(转)
serialVersionUID的作用(转)
[转]学习win10的bash使用ssh连接远程服务器
[转]使用 Travis CI 部署你的 Hexo 博客
【转】H5
【转】Virtual DOM
【转】hexo博客图片问题
【转】V8 之旅: 垃圾回收器
关于react-redux中Provider、connect的解析
【转】webpack4
-
原文地址:https://www.cnblogs.com/ftae/p/9753295.html
Copyright © 2020-2023
润新知