随笔分类 - 动态规划
摘要:容斥+分治NTT. 令 $dp[i]$ 表示以 $i$ 结尾的方案数. 如果只有小于号的话 $dp[i]$ 是非常好求的:$\frac{n!}{\prod a_{i}}$ 即总阶乘除以每一个小于号连续段. 有大于号的时候考虑容斥: 遇到第一个大于号的时候先不考虑当前位置关系,方案数就是 $dp[j]
阅读全文
摘要:这道题的题意不太明确. 应该是两个序列 $a,b$ 不同,当且仅当存在位置 $i$ 使得 $a[i]$ 不等于 $b[i]$. 朴素的 DP 非常好列:$f[i][j]$ 表示选了 $i$ 个数,且值域为 $[1,j]$ 的总价值和. 那么有 $f[i][j]=f[i-1][j-1] \times
阅读全文
摘要:数位 DP. 题意:给定 $n \leqslant 10^{700}$,求 $1$ 到 $n$ 中每个数在各数位排序后得到的数的和. 这道题从整体上看上去貌似不太可做,不妨从每一位开始考虑. 比如说我们可以考虑第 $i$ 位为 $k$ 的数目,然后乘上 $10^i$ 后就是这一位的贡献了. 这么做的
阅读全文
摘要:现在看来这道题就简单了. 首先要知道,树形 DP 的复杂度是 $O(n^2)$ 的(通过严格控制子树大小,均摊下来一个状态只会贡献 n 次). 然后这道题要求选的个数最多为 $k$,所以复杂度就是 $O(nk)$ 的. 设 4 个状态:$f[x][y][0/1],g[x][y][0/1]$ 分别代表
阅读全文
摘要:刚开始想出了一个分治做法,但是比较麻烦,需要分 4 中情况讨论. 后来偷看了一眼标签发现是线段树,然后就想出了这个线段树做法. 考虑序列以 $r$ 为右端点的答案,有 $\sum_{l=1}^{i} max(l,i)-min(l,i)=i-l$. 其中这个条件可以写成 $max(l,i)-min(l
阅读全文
摘要:令 $ok[l][r]$ 表示 $[l,r]$ 是否都能删掉,$g[l][r],f[l][r]$ 分别表示能否删成只剩左/右端点. 然后按照区间 DP 的方式来转移上述 3 个状态,得到最终的 $ok[l][r]$. 最后再令 $ans[i]$ 表示 $1$ ~ $i$ 的最优解,然后枚举 $ok[
阅读全文
摘要:比较好的一道虚树题. 建出虚树,然后计算虚树中距离点 $x$ 最近的关键点,这个来一次树形dp+换根即可实现. 难点在于计算 $x$ 到 $x$ 父亲这一段所有节点归属于谁(肯定属于 $x$ 的最近点或 $x$ 父亲最近点). 这里的话肯定可以二分出拐点(拐点以前属于 $x$,拐点以后属于 $y$)
阅读全文
摘要:打的 vp,花了 1h 30min 切了前 6 个,后来花了 20min 把最后一题也切掉了. 难度不大,但是想要进前 10 的话手速还是要快一点. A - Short Substrings 观察一下字符串,然后发现相同的保留一个就行. #include <bits/stdc++.h> #defin
阅读全文
摘要:这道题中我们要考虑这么几件事情: 1.前 2 个数是什么.2.是否已经合法了. 3.是否顶上界.4.是否有4/8 那么设状态的时候就是 $f[num_{i-1}][num_{i-2}][state][l][4][8]$ 记忆化搜索的时候如果搜过该状态且补丁上界就返回. 然后转移的时候注意:1.是否新
阅读全文
摘要:这道题细节并不算太多,但是求方案数的时候一定不要乱取模! 如果非要取模的话也要遵循欧拉定理. code: #include <bits/stdc++.h> #define N 57 #define ll long long #define mod 10000007 #define setIO(s)
阅读全文
摘要:数位dp. 细节真的很多. 1. 考虑清楚每个数的贡献. 2. 0 特殊考虑. code: #include <bits/stdc++.h> #define ll long long #define setIO(s) freopen(s".in","r",stdin) using namespace
阅读全文
摘要:基本上把数位dp那一套给忘了,今天重学一遍. 感觉采用递推的方式还是蛮方便的,然后要注意几个细节: 1. 通常算 f(x+1)=calc(1,x),这样更方便算一些. 2. 每种小于最大长度的所有结果都要累加. 3. 很多时候不要忘记 0 的贡献. 4. 要特判前缀合不合法. code: #incl
阅读全文
摘要:感觉是比较基础的子集 DP. 令 $dp[S]$ 表示点集 $S$ 构成的价值和,然后枚举最后一个区域就行. 也就是 $dp[S]=\sum_{T \subseteq S } dp[S-T] \times (\frac{sum[T]}{sum[S]})^k$ 化简得 $dp[S] \times su
阅读全文
摘要:满分做法需要用到很神仙的优化方式,这里只给出 部分分的做法. 想出了 70pts 做法还是十分开心的. 开始的时候先想了一个 35 pts 做法: 考虑连续段,那么连续段的长度不会超过 $K$,高度不会超过 $K$,所以 $K \leqslant 9$ 的状态都能搜出来. 然后令 $f[i]$ 表示
阅读全文
摘要:由于集合内的数不能有交集,所以显然是子集 dp 的形式. 但是这道题为了不算重不太能用 FWT 优化,直接暴力 dp 的话是 $O(3^{18})$ 的,洛谷上开 O2 能过. 转移 DP 的时候一定注意是 $many[i] \times f[j]$,而不是 $f[i] \times f[j]$,否
阅读全文
摘要:按照套路,考虑将数字从小到大插入到序列中. 令 $f[i][j]$ 表示将 $1$ ~ $i$ 插入到序列中,形成了 $j$ 对不合法的方案数. 然后考虑将 $i+1$ 插入时的情况: 1. 插入到不合法的空位中,消掉一个不合法. 2. 插入到合法的空位中 3. 插入到 $i$ 旁边,形成一个不合法
阅读全文
摘要:思路非常巧妙,令 $f[i][j]$ 表示前 $i$ 个数,最大值不大于 $j$ 的权和. 转移的话枚举最大值出现的第一个位置,乘上该位置对应的贡献,然后发现最大值将 $1$ ~ $i$ 分成了两半. 然后两个部分又是互不干扰的子问题,转移一下就行. 把细节都提前考虑清楚后都不用怎么调. code:
阅读全文
摘要:显然取对数,然后二分答案进行 01 分数规划. 设 $f[i][j]$ 表示在 AC 自动机上的点 $i$ ,匹配到了 $j$ 位的最大价值. 转移的时候判断一下当前是点还是数字,然后在 AC 自动机上的终止节点上算一下贡献就行. 构建 AC 自动机的时候要注意:点 $i$ 的价值是 val[i]+
阅读全文
摘要:非常有意思的 dp,很难想出来吧. 如果对着图去想,很难有思路,所以可以把图上的问题转化为序列问题. 我们发现,如果一个点集合法,当且仅当这个点集构成一个不降序列,且其他点都与这个点集形成逆序对. 令 $f[i]$ 表示由 $1$ ~ $i$ (选 $i$ )构成的合法方案数. 然后如果不选一个元素
阅读全文
摘要:这个状压状态时显然的,但是总状态数有 $\binom{K}{P}$. 好在题目中有一个要求,就是每个格子必须经过一次,所以说我们压缩的长度为 $P$ 的状态中首位必为 1. 那么状态数就减小为 $\binom{K-1}{P-1}$,来一个矩阵乘法就行了. code: #include <cstdio
阅读全文

浙公网安备 33010602011771号