<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>DP on Inftopia</title>
    <link>https://inftress.pages.dev/tags/dp/</link>
    <description>Recent content in DP on Inftopia</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Thu, 04 Jun 2026 19:19:51 +0800</lastBuildDate>
    <atom:link href="https://inftress.pages.dev/tags/dp/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Random Kth Max</title>
      <link>https://inftress.pages.dev/posts/random-kth-max/</link>
      <pubDate>Thu, 04 Jun 2026 19:19:51 +0800</pubDate>
      <guid>https://inftress.pages.dev/posts/random-kth-max/</guid>
      <description>&lt;p&gt;简单题。&lt;/p&gt;
&lt;p&gt;首先看到这个题目第一眼就要想到结论：$n$ 个在 $[0,1]$ 间均匀随机的数的第 $k$ 小期望是 $\cfrac{k}{n + 1}$。&lt;/p&gt;
&lt;p&gt;这个范围相当宽裕，我们只要给出一个 $O(\text{poly } n)$ 的即可&lt;/p&gt;
&lt;p&gt;然后我们考虑枚举答案所在区间，我们现在枚举到了 $[t - 1, t]$。&lt;/p&gt;
&lt;p&gt;然后我们想知道有多少个随机数落在这个区间里，多少个落在区间左，多少个落在区间右。我们如果知道这些我们可以直接通过那个结论算出对应的期望。&lt;/p&gt;
&lt;p&gt;然后我们就是想要知道在钦定了左中右的数量后有多大概率。&lt;/p&gt;
&lt;p&gt;我们可以使用二维背包，直接做即可。时间复杂度四次方。&lt;/p&gt;</description>
    </item>
    <item>
      <title>彩绘</title>
      <link>https://inftress.pages.dev/posts/%E5%BD%A9%E7%BB%98/</link>
      <pubDate>Sat, 30 May 2026 23:33:04 +0800</pubDate>
      <guid>https://inftress.pages.dev/posts/%E5%BD%A9%E7%BB%98/</guid>
      <description>&lt;p&gt;简单题，但脑抽了。&lt;/p&gt;
&lt;p&gt;这个题目本质上就是让我们算这个每个位置的系数。（因为他可以通过类似哈希来检验你的系数，就算你有不算出系数的方法，那通过他的不同数据一定能唯一确定系数）&lt;/p&gt;
&lt;p&gt;好的我们很容易得到一个 $O(n^3)$ 的做法，设 $f_{i,j}$ 为第 $i$ 轮第 $j$ 个数的系数，然后枚举你当前选择哪一个。然后便是 $O(n^2)$ 的。你发现对每个 $f_{i,j}$ 他只从 $f_{i-1,j}$ 和 $f_{i-1,j-1}$ 转移过来。然后就方了。&lt;/p&gt;
&lt;p&gt;如何继续优化？显然你可以把每轮的除以 $i-1$ 和除以 $2$ 拎出来。然后你对着剩下的表进行干瞪。你通过瞎试发现他一定是 $\binom{i-1}{j-1}$ 的倍数。然后你对他除完之后的进行因式分解。然后发现除完之后是两个双阶乘的积。然后你就糊里糊涂地做完了，但并不知道这个组合意义。这不乏为一种方法但多少有点唐了。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;然后说正解，实际上你发现我糖丸了。你还可以继续拎。具体思想就还是&lt;strong&gt;考虑不变量&lt;/strong&gt;以及&lt;strong&gt;图论建模&lt;/strong&gt;。我们把他变成在自动机上走，然后你发现你每增加 $j$ 就会乘上固定贡献，每增加 $i-j$ 也会乘上固定贡献。于是我们发现这两个贡献与你走的路径无关，乘上的东西都是一定的。然后贡献就是两个双阶乘，而你的路径数就是 $\binom{i-1}{j-1}$。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Sequence Growing Hard</title>
      <link>https://inftress.pages.dev/posts/sequence-growing-hard/</link>
      <pubDate>Sat, 23 May 2026 20:07:48 +0800</pubDate>
      <guid>https://inftress.pages.dev/posts/sequence-growing-hard/</guid>
      <description>&lt;p&gt;这是一个“分步”进行构造的过程，每一步关联不大。所以我们先研究每一步有什么性质。&lt;/p&gt;
&lt;p&gt;假设你现在有长度为 $n$ 的序列，你需要在第 $i$ 个元素之后插入一个 $x$，字典序变大当且仅当？&lt;/p&gt;
&lt;p&gt;你考查你插入后的序列，找到那个你插入的元素。其后面第一个第一个与前一个数字不同的数字比他前面的数字大，或者其后面的所有数字相等。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;好吧我错了。&lt;/p&gt;
&lt;p&gt;考虑加元素是困难的，考虑删元素。&lt;/p&gt;
&lt;p&gt;然后你发现对于一个连续段来讲你删任意一个都是等价的，所以我们钦定每次删最右边那个。&lt;/p&gt;
&lt;p&gt;这相当于每次删 $a_i &amp;gt; a_{i+1}$ 的地方。这看起来容易多了。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;我错了，我好菜。&lt;/p&gt;
&lt;p&gt;我们设 $f_{i,j}$ 为考虑长度为 $i$，值域为 $k$ 的。&lt;/p&gt;
&lt;p&gt;我一直在试图一个一个加，结果发现还是做不了。&lt;/p&gt;
&lt;p&gt;主要是你发现这个东西你还是要知道全局信息。&lt;/p&gt;
&lt;p&gt;题解说：我们分治！&lt;/p&gt;
&lt;p&gt;然后你直接枚举 $1$ 的出现位置和出现时间，然后分成前后两半。&lt;/p&gt;
&lt;p&gt;做完了。&lt;/p&gt;
&lt;p&gt;为什么我这么蠢啊。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Two Characters, Two Colors</title>
      <link>https://inftress.pages.dev/posts/two-characters-two-colors/</link>
      <pubDate>Sat, 23 May 2026 10:38:36 +0800</pubDate>
      <guid>https://inftress.pages.dev/posts/two-characters-two-colors/</guid>
      <description>&lt;p&gt;首先把如果 $b &amp;gt; r$ 那肯定选蓝，一定不劣。&lt;/p&gt;
&lt;p&gt;然后我们就再把 $r-=b$ 然后就变成了你选一个子序列使得 $\sum r - 逆序对数$ 最大。&lt;/p&gt;
&lt;p&gt;然后我们显然 DP 记录前面用了多少个 $0$。&lt;/p&gt;
&lt;p&gt;$f_{i,j}$ 表示当前考虑了 $[1,i]$ 的下标，前面用了 $j$ 个 $1$。&lt;/p&gt;
&lt;p&gt;然后转移显然好转移，考虑优化。&lt;/p&gt;</description>
    </item>
    <item>
      <title>Permutation and Minimum</title>
      <link>https://inftress.pages.dev/posts/permutation-and-minimum/</link>
      <pubDate>Thu, 21 May 2026 22:35:45 +0800</pubDate>
      <guid>https://inftress.pages.dev/posts/permutation-and-minimum/</guid>
      <description>&lt;p&gt;首先我们发现其实这个东西是可以分类讨论的。&lt;/p&gt;
&lt;p&gt;对于 $(2i-1,2i)$ 这样的二元组讨论。&lt;/p&gt;
&lt;p&gt;若两者都不是 $-1$ 则直接跳过。（甚至可以直接离散化掉）&lt;/p&gt;
&lt;p&gt;若两者都是 $-1$ 则可以放在一起算。具体来讲，我们可以数一共有多少个这样的二元组，然后我们只要算全是 $-1$ 的答案，然后再乘上把这些二元组去掉之后的答案即可。（因为对于其他的二元组确定的情况下，实际上的方案数总是相同的）&lt;/p&gt;
&lt;p&gt;比如有 $k$ 个二元组，然后你考虑钦定哪些数作为二元组中的更小值，然后再排列一下。钦定的方案数为 $Catalan(k)$。因为注意到你本质上要求对于任意前缀，选的作为最小值的个数 $\ge$ 作为最大值的个数。然后排列即为 $k!$，即答案为 $Catalan(k)k!$。&lt;/p&gt;
&lt;p&gt;现在我们只要专心考虑恰好有一个 $-1$ 的即可。&lt;/p&gt;
&lt;p&gt;我们先考虑简单的情况，假设整个排列都是一个 $-1$ 和一个非 $-1$。&lt;/p&gt;
&lt;p&gt;然后这个时候开始 DP。&lt;/p&gt;
&lt;p&gt;我们发现这个顺序根本不重要，我们只要给他们染色然后配对即可。最终再乘上阶乘。&lt;/p&gt;
&lt;p&gt;我们如法炮制，还是按值域排在一起，发现我们可以从大到小做。&lt;/p&gt;
&lt;p&gt;我们称已经被填入的为白点，我们要填的是黑点。&lt;/p&gt;
&lt;p&gt;设 $f_{i,j,k}$ 为当前处理了值域在 $[i,n]$ 内的东西，其中钦定 $j$ 个 $[1,i)$ 中的黑点，$k$ 个 $[i,n]$ 内的黑点已经被预留了。&lt;/p&gt;
&lt;p&gt;然后直接转移即可。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;调半天过不了样例。&lt;/p&gt;
&lt;p&gt;问题在于，实际上你不能在 dp 的时候简单地只看你留了几个来考虑这个 $(-1,-1)$ 二元组，你要把他放进去算，因为实际上这个预留与实际上还是有一些区别的，因为你可能可以填上这个东西。&lt;/p&gt;</description>
    </item>
    <item>
      <title>AtCoder Quality Problem</title>
      <link>https://inftress.pages.dev/posts/atcoder-quality-problem/</link>
      <pubDate>Thu, 21 May 2026 18:04:02 +0800</pubDate>
      <guid>https://inftress.pages.dev/posts/atcoder-quality-problem/</guid>
      <description>&lt;p&gt;我意识到了我做 DP 的严重问题。我非常习惯于说去推结论和性质，结果迟迟没有开始试图设计状态。对 DP 理解的非常的不深刻。在推性质的时候应该主动像 DP 上靠。而不是先推再说。要主动地设计状态，尝试几种经典的状态设计。然后试图找出关系。或者是先找出&lt;strong&gt;子结构&lt;/strong&gt;之间的联系。&lt;/p&gt;
&lt;p&gt;DP 的本质就是子结构。要主动洞察这个题目有哪些子结构，以及他们之间的良好性质，而不是仅靠“发现”。&lt;/p&gt;
&lt;p&gt;我觉得我设计暴力 DP 这件事比 DP 优化更困难。因为我并没有养成这种良好的思维习惯。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;开始正题。&lt;/p&gt;
&lt;p&gt;这个题目首先就是我们 feel 一下这个题目。&lt;/p&gt;
&lt;p&gt;一个 native 的想法是考虑从小到大以 popcnt 为层推进。然后呢你其实可以把他看成一个金字塔。然后你想一下，比如说你当前先把单个元素染个色。然后对于横跨的，怎么办？实际上对于这些横跨的不能随便染色，反例：RBBR 13 24 R 14 23 B 然后就炸了。&lt;/p&gt;
&lt;p&gt;然后呢我就摆了，也许是畏惧吧。&lt;/p&gt;
&lt;p&gt;你其实可以推进一步，你思考为什么会炸。&lt;/p&gt;
&lt;p&gt;因为 R 和 B 的并都是 S。&lt;/p&gt;
&lt;p&gt;然后显然 R 和 B 的并不能都不是 S。&lt;/p&gt;
&lt;p&gt;然后如果 S 是 R 那一定是 R 的并是 S。反过来同理。&lt;/p&gt;
&lt;p&gt;实际上现在你可以直接开始试图设计状态了。&lt;/p&gt;
&lt;p&gt;比如你很经典地你设 $f_{S,0/1}$ 为 $S$ 内染色，然后颜色为 $0/1$。然后这个时候你想怎么转移。&lt;/p&gt;
&lt;p&gt;你发现你好转移啊，你找这个并不是当前颜色的并。然后你发现其实这个并一定得是对应的 $f$ 然后你直接转移即可。&lt;/p&gt;
&lt;p&gt;优化用脚优化。你直接一个一个加即可，套路。&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Third Grace</title>
      <link>https://inftress.pages.dev/posts/the-third-grace/</link>
      <pubDate>Wed, 20 May 2026 22:27:29 +0800</pubDate>
      <guid>https://inftress.pages.dev/posts/the-third-grace/</guid>
      <description>&lt;p&gt;观察 1: 这个区间其实跟左端点的关系不大，跟右端点关系更大。&lt;/p&gt;
&lt;p&gt;于是我们可以想到从左到右考虑，于是乎我们发现了一个 $O(n^2)$ 的做法。&lt;/p&gt;
&lt;p&gt;我们设我们当前决策了是否要激活 $[1,i]$ 且激活了 $i$ 的最大代价为 $f_i$。&lt;/p&gt;
&lt;p&gt;然后转移就是枚举 $j &amp;lt; i$，然后减去多于代价，加上新的。&lt;/p&gt;
&lt;p&gt;我们考虑优化他。&lt;/p&gt;
&lt;p&gt;首先新的贡献是跟 $j$ 无关的。&lt;/p&gt;
&lt;p&gt;然后剩下的呢，我们考虑我们往右扫。维护右端点在 $i$ 右边的区间。然后你把他们的左端点放在线段树里，你每删除一个线段，就在对应的区间内将线段树减一。然后相当于要区间 $y_i$ 加，区间 $x_iy_i$ 最小值。然后你发现这是 KTT 板子。&lt;/p&gt;
&lt;p&gt;做完了。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
