「杂题乱写」Codeforces 上 DP 乱写
作为衡中 OIer,我们要紧随 SoyTony 步伐,建设新时代 SoyTony 特色博客 .
原博客:SoyTony .
CF607B Zuma
给一个长度为 \(n\) 的字符串 \(a\),每次可以选一个回文子串消掉,问至少消几次能消完 .
\(1\le|\Sigma|\le n\le 500\) .
魔幻区间 DP .
首先处理长度不大于 \(2\) 的答案,这是平凡的 .
然后考虑如果对于 \(a_l = a_r\),那么消除 \([l+1,r-1]\) 的时候肯定能顺便把 \(a_l,a_r\) 也消了,否则枚举断点拆成两半转移即可 .
时间复杂度 \(\Theta(n^3)\) .
CF178F Representative Sampling
给 \(n\) 个字符串,要求选出一个 \(k\) 元子集 \(\{a_k\}\),使得
\[\sum_{i=1}^n\sum_{j=i+1}^n|\operatorname{lcp}(a_i,a_j)| \]最大 .
\(n\le 2000\),字符串长度不大于 \(500\) .
(F2:\(n\le 100\))考虑 Trie 树上 DP,令 \(dp_{u,k}\) 表示 \(u\) 的子树选了 \(k\) 个串的答案,转移是树形背包,时间复杂度 \(\Theta(ck)\),\(c\) 是 Trie 树点数,无法得到满分 .
把树压缩一下,留下表示字符串末尾节点的虚树,这样就有 \(c=\Theta(n)\),时间复杂度即为 \(\Theta(nk)\),可以通过 .
CF1774E Two Chess Pieces
\(n\) 个点的树上两个指针 A, B,要求任意时刻 A, B 间距离不超过 \(d\) .
A,B 有一些必须经过的结点,每次操作可以将 A 或 B 移动一步,问 A, B 从根节点出发遍历所有点后回到根的最小步数 .
\(2\le d\le n\le 2\times 10^5\) .
处理每个点 \(u\) 子树内最深结点深度 \(f(u)\),维护 \(dp_{1,u}\) 表示只靠一个指针环游 \(u\) 子树内结点的答案,\(dp_{2,u}\) 表示两个指针环游 \(u\) 子树内的答案 .
对于每条边 \((u,v)\),如果 \(f(v)-\operatorname{dep}(u)>d\) 或者 \(u\) 子树内有 A, B 都要去的点,那么对于这条边的 \(dp_{2,u}\) 就必须有 A,B 移动的四次贡献(这时候 \(dp_{1,u}\) 未定义,不过也不需要可以不管),否则可以借助 \(dp_{1,u}\) 的答案走两步转移到祖先(此时一定可以只用一个指针完成任务,另一个不用动).
实际操作的时候可以把每个 \(dp_1\) 加一,比较好转 .
时间复杂度 \(\Theta(n)\) .
CF1783D Different Arrays
给一个序列 \(\{a_n\}\),对于所有 \(1<i<n\),执行操作 \(a_{i+1}\gets a_{i+1}+a_i\),\(a_{i-1}\gets a_{i-1}-a_i\) 或 \(a_{i+1}\gets a_{i+1}-a_i\),\(a_{i-1}\gets a_{i-1}+a_i\) .
问最后可能有多少种不同的序列 .
\(1\le n,a_i\le 300\) .
令 \(dp_{i,j}\) 表示到第 \(i\) 个操作前 \(a_i=j\) 的答案,转移的时候对于 \(j=0\) 两种操作生成序列相同否则不同 .
这样即可做到 \(\Theta(nV)\) .
CF1771D Hossam and (sub-)palindromic tree
给一棵 \(n\) 个点的树,每个点上有一个字符,找一条最长的链使得链上节点上的字符顺次链接为回文串 .
\(\displaystyle\sum n\le 2\times 10^3\) .
考虑序列上的问题就是区间 DP,令 \(dp_{l,r}\) 为 \([l,r]\) 的答案,则
上树的话考虑每条链 \(u,v\) 往里缩一格得到的转移即可 .
转移点可以倍增预处理,时间复杂度 \(\Theta(n^2\log n)\) .
CF1761D Carry Bit
给两个整数 \(n,k\),问有多少 \((a,b)\) 满足 \(0\le a,b<2^n\) 且 \(a+b\) 二进制下的进位数为 \(k\) .
\(0<k\le n\le 10^6\)
考虑 DP,\(dp_{i,j,0/1}\) 表示 \(1\dots i\) 共进了 \(j\) 位,最后进位 / 未进位的方案数 .
经过朴素的分类讨论可以得到转移:
观察可以发现,如果对于每一位的进位 / 未进位已经钦定完毕,那么只有相邻状态不一样的位置会产生贡献,这个等价于连续段数量 .
于是考虑枚举连续段数量 \(i\),然后讨论首位是否进位后插板法即可 .
时间复杂度 \(\Theta(n)\) .
需要注意一下 corner case .
CF1743E FTL
有两艘飞船,第 \(i\) 艘飞船的攻击力为 \(p_i\),每一次攻击的充能时间为 \(t_i\),一开始两艘飞船没有充能 .
现在要打败敌方飞船,敌方飞船的血量为 \(h\),防御力为 \(s\) . 对于一次攻击力为 \(P\) 的攻击,敌方飞船的血量会减少 \((P-s)\) . 攻击的攻击力为所有参与攻击的飞船攻击力之和 .
敌方飞船血量不大于 \(0\) 即被打败,问最少需要多少时间能够打败敌方飞船 .
\(2\le h,p_1,p_2\le 5000\) .
考虑两个飞船同时攻击就相当于回复到初始状态,于是 DP 处理对于每个 \(i\in[0,h]\) 处理最后一次两个一起攻击前面都不一起攻击打掉 \(i\) 格血的答案 .
然后 DP 统计一下把上面的东西组合起来的答案即可 .
时间复杂度 \(\Theta(h^2)\) .
(注:不会更新,纯属搞笑用)
以下是博客签名,正文无关
本文来自博客园,作者:Jijidawang,转载请注明原文链接:https://www.cnblogs.com/CDOI-24374/p/17135326.html
版权声明:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0)进行许可。看完如果觉得有用请点个赞吧 QwQ