随笔分类 - 算法-动态规划
摘要:对 S 的长度为 x 的后缀,发现 x - h(x) 有两个很好的性质。(1) 单调不降。(2) 值域在 [-|T|, |T|] 这个很小的范围内。于是考虑对这个分段函数进行 DP。将函数的值域作为 DP 状态,位置 x 作为 DP 值。转移和朴素 DP 一样,分三种情况。DP 边界需要注意,细节挺妙。
阅读全文
摘要:一个结论是,不存在大小大于 2 的环。于是我们只需要保证图连通即可。从高到低考虑每一位,把数分成当前位为 0 的集合和当前位为 1 的集合,则为保证连通,必须有至少一个集合,大小小于 2。枚举删哪个集合,然后递归即可。本质是在 Trie 树上树形 DP。
阅读全文
摘要:考虑把 DAG 分层,用状压 DP 来实现这个过程。每次转移增加一层,必须满足所有能到达新层的点,都在原点集里出现过。把每条边的代价,分摊到它跨过的每一层里。也就是每次转移,代价是:所有起点已经在 S 里,终点不在 S 里的边的边权之和。
阅读全文
摘要:考虑把整个方案紧密排列在一起,需要的格子数是 sum (p(i) - p(i - 1)) + 1,是 O(n^2) 级别的。剩下的格子插板插进去即可,可以用组合数计算。而这 O(n^2) 个格子的方案,可以用 DP 计算出来。最后插板乘组合数时,由于模数不是质数没有逆元,不好直接求。需要用先矩阵快速幂预处理出 C(下界, 0...n),再把上下界之间的都暴力递推出来
阅读全文
摘要:树形DP。转移时将儿子按 h 的大小关系分成三类。枚举和 h[u] 相等的儿子里,有几个定向为向上,则可以贪心地取 dp[v][0] - dp[v][1] 前若干大的。
阅读全文
摘要:转化为最小化每一段的代价之和。设 dp[i][j][k] 表示考虑了前 i 个位置,第 i 个位置放了 1,用了 j 次操作,前 i 个位置共放了 k 个 1,此时的最小代价和。转移时枚举下一个 1 的位置,时间复杂度 O(n^5),可以用斜率优化优化到 O(n^4 log n)
阅读全文
摘要:把覆盖,转化成插入,由此可以得到一个O(n^2)的DP。观察DP转移,发现答案是一堆短多项式的乘积。一般做法是分治FFT,不过本题里可以用倍增+二项式定理去掉一个log。
阅读全文
摘要:设dp(i)表示i棵树必胜的方案数(第一棵树的根可以任意,所有根的方案数加起来)。转移时在前面添加一棵树。枚举添加的这棵树的根。发现系数之和可以预处理出来。不过对每个根都预处理一次,复杂度就是n^2了,所以要换根。求出系数之后,用矩阵快速幂优化这个DP即可。
阅读全文
摘要:m=n-1时一定有解,策略是取最小的和最大的原材料拼成一道菜,然后转化为m,n分别小1的子问题递归下去。m>=n时,可以先取最大的原材料,直到m=n-1。m=n-2时,用DP将所有原材料,划分成两个m=n-1的集合。DP的状态设计比较巧妙,同时需要用到bitset优化
阅读全文
摘要:先做一个二维DP:dp[u][i]表示点u的祖先边中离它最近的,颜色为1的边,深度为i,此时节点u子树内的边的染色方案数。然后把第二维搬到线段树上,做线段树合并
阅读全文
摘要:朴素DP,设dp[i][u]表示第i个时刻在第u个点,总共得到的最大愉悦值。用矩阵快速幂优化,需要重新定义一种max运算的矩阵乘法,它也具有结合律。拆边可以完成转移。改成拆点可以进一步优化复杂度。我们要对k个美食节间的每一段时间单独做一次快速幂,太慢了。发现转移矩阵是一样的,可以预处理转移矩阵的2^x幂,就变成log T次向量乘矩阵的乘法。时间复杂度O((5n)^3 log T + k*(5n)^2 log T)
阅读全文
摘要:树形DP。设dp[u][x]表示,u的所有祖先(不含u)对u的贡献和为x时,u的子树内最少还需要进行多少次操作。设u和它的祖先的贡献和为y。则dp[u][x]可以从sum(dp[v][y]) + [y!=x] 转移过来。x可能很大,不过可以证明,我们只需要考虑所有l,r这些端点。所以离散化一下即可
阅读全文
摘要:转化为求A串一个区间和B串的最长公共子序列。预处理一个dp[i][j][k],表示从A串的i,B串的j开始,长度为k的公共子序列,在A串里的结尾位置最小是多少。转移从dp[i+1]转移到dp[i],考虑第i位选不选即可。回答询问时,枚举j,k,如果dp[L][j][k]<=R,可以用k更新答案
阅读全文
摘要:如果已经知道结果串t,考虑s能不能得到t,可以做一个贪心“匹配”。知道这个贪心的策略后,考虑本题要计算所有t的数量,那么可以DP。设dp[i]表示有多少t能贪心匹配到s的前i位。转移时考虑t的下一位是1还是0即可。
阅读全文
摘要:区间DP。dp[i][j]表示只考虑被[i,j]完全包含的区间,能达到的最大价值。转移时枚举一个k(i<=k<=j),表示把1尽可能集中到第k列。设所有跨过k,且被[i,j]完全包含的区间数量为cnt(k),则新增的贡献就是cnt(k)^2。
阅读全文
摘要:考虑使用一个O(2^m*m)的状压DP解决这个问题。发现需要预处理出每个装修队集合,能装修的边集的并的大小。边集并,容斥一下,转化为求边集交。而边集交,只和点集交的大小有关。于是又转化为求点集交。考虑每个点的贡献,做高维后缀和即可。
阅读全文
摘要:因为border的border还是border,所以一个串的最小border,也必须是无界单词。设dp[i]表示长度为i的无界单词数量,转移时,枚举最小border的长度(长度一定不超过floor(i/2))j,dp[i]可以从dp[j]转移过来。对第二问,可以逐位确定,每次对后面还未确定的位,做类似的DP。
阅读全文
摘要:假设这n个数,最终就是从大到小严格降序的。可以做状压DP:对相邻两个数的大小关系(小于还是等于)进行状压。转移时枚举这个n个数下一个二进制位上分别是什么。发现S的这k次重复,每次的转移都是一样的。可以把转移预处理出来,然后做矩阵快速幂。
阅读全文