<?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>LeetCode on Weiuou的博客</title><link>https://blog.weiuou.top/tags/leetcode/</link><description>Recent content in LeetCode on Weiuou的博客</description><image><title>Weiuou的博客</title><url>https://blog.weiuou.top/avatar.png</url><link>https://blog.weiuou.top/avatar.png</link></image><generator>Hugo</generator><language>zh-cn</language><copyright>Weiuou</copyright><lastBuildDate>Sat, 01 Aug 2026 15:00:00 +0800</lastBuildDate><atom:link href="https://blog.weiuou.top/tags/leetcode/index.xml" rel="self" type="application/rss+xml"/><item><title>力扣双周赛 187 题解：字符串构造、峰值公式、逆序对与区间 DP</title><link>https://blog.weiuou.top/posts/leetcode-biweekly-contest-187-editorial/</link><pubDate>Sat, 01 Aug 2026 15:00:00 +0800</pubDate><guid>https://blog.weiuou.top/posts/leetcode-biweekly-contest-187-editorial/</guid><description>LeetCode 第 187 场双周赛四题完整中文题解，涵盖字符串分桶构造、严格交替序列峰值公式、三类别逆序对和不重叠区间 DP，附 Java 17 标程、正确性证明、复杂度分析与完整视频讲解。</description><content:encoded><![CDATA[<h2 id="完整视频讲解">完整视频讲解</h2>
<p>🎬 <a href="https://www.bilibili.com/video/BV1EvG36wE9v">前往 Bilibili 观看《力扣双周赛 187 四题完整题解》</a></p>
<p>视频章节：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">00:00 3992 - 重新排列字符串以避免字符对
</span></span><span class="line"><span class="cl">02:02 3993 - 交替数列的最大元素
</span></span><span class="line"><span class="cl">04:01 3994 - 划分数组的最少相邻交换次数
</span></span><span class="line"><span class="cl">06:05 3995 - 转换字符串的最小成本 III
</span></span></code></pre></div><p>本文整理第 187 场力扣双周赛的四道题。四份 Java 17 代码均经过本地编译、官方样例、边界用例与差分测试；本次采用本地模式，没有向力扣账号提交代码，因此不把本地验证写成平台 <code>Accepted</code>。</p>
<h2 id="题目总览">题目总览</h2>
<table>
	<thead>
			<tr>
					<th>题号</th>
					<th>题目</th>
					<th>难度</th>
					<th>核心方法</th>
					<th>时间复杂度</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>3992</td>
					<td><a href="https://leetcode.cn/problems/rearrange-string-to-avoid-character-pair/">重新排列字符串以避免字符对</a></td>
					<td>Easy</td>
					<td>三类字符分桶构造</td>
					<td><code>O(n)</code></td>
			</tr>
			<tr>
					<td>3993</td>
					<td><a href="https://leetcode.cn/problems/maximum-value-of-an-alternating-sequence/">交替数列的最大元素</a></td>
					<td>Medium</td>
					<td>峰值上界与构造公式</td>
					<td><code>O(1)</code></td>
			</tr>
			<tr>
					<td>3994</td>
					<td><a href="https://leetcode.cn/problems/minimum-adjacent-swaps-to-partition-array/">划分数组的最少相邻交换次数</a></td>
					<td>Medium</td>
					<td>三类别逆序对计数</td>
					<td><code>O(n)</code></td>
			</tr>
			<tr>
					<td>3995</td>
					<td><a href="https://leetcode.cn/problems/minimum-cost-to-convert-string-iii/">转换字符串的最小成本 III</a></td>
					<td>Hard</td>
					<td>不重叠区间前缀 DP</td>
					<td><code>O(nRL)</code></td>
			</tr>
	</tbody>
</table>
<h2 id="3992-重新排列字符串以避免字符对三类字符分桶">3992. 重新排列字符串以避免字符对｜三类字符分桶</h2>
<p><img alt="3992 字符分桶构造" loading="lazy" src="/images/posts/leetcode-biweekly-contest-187/3992.png"></p>
<h3 id="题意">题意</h3>
<p>给定字符串 <code>s</code> 和两个不同字符 <code>x</code>、<code>y</code>。可以任意重排 <code>s</code>，要求结果中每个 <code>y</code> 都出现在每个 <code>x</code> 之前，返回任意一个满足条件的排列。</p>
<h3 id="核心思路">核心思路</h3>
<p>题目只约束 <code>x</code> 与 <code>y</code> 的相对位置，其他字符放在哪里都不影响合法性。把字符分成三类：</p>
<ul>
<li><code>Y</code>：所有字符 <code>y</code>；</li>
<li><code>M</code>：所有既不是 <code>x</code> 也不是 <code>y</code> 的字符；</li>
<li><code>X</code>：所有字符 <code>x</code>。</li>
</ul>
<p>最直接的合法骨架就是：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Y + M + X
</span></span></code></pre></div><p>代码先统计 <code>x</code>、<code>y</code> 的数量，再选择一个确定性布局：</p>
<ul>
<li><code>countY &lt; countX</code>：输出 <code>Y + M + X</code>；</li>
<li>否则：按原顺序输出所有非 <code>x</code> 字符，再输出全部 <code>x</code>，即 <code>Non-X + X</code>。</li>
</ul>
<p>第二个布局仍然合法，因为 <code>x != y</code>，所以所有 <code>y</code> 都属于前面的 <code>Non-X</code> 部分。</p>
<p>例如 <code>s = &quot;zzayzb&quot;</code>、<code>x = 'z'</code>、<code>y = 'a'</code>：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Y = a
</span></span><span class="line"><span class="cl">M = yb
</span></span><span class="line"><span class="cl">X = zzz
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">answer = aybzzz
</span></span></code></pre></div><h3 id="正确性证明">正确性证明</h3>
<p>分两部分证明。</p>
<p>首先证明结果是原串的排列。第一种分支中，<code>Y</code>、<code>M</code>、<code>X</code> 三类两两不交，并完整覆盖 <code>s</code> 的所有字符；第二种分支中，所有非 <code>x</code> 字符与全部 <code>x</code> 同样两两不交并完整覆盖原串。因此每个输入字符都恰好写入一次。</p>
<p>再证明顺序条件。两种分支都把全部 <code>x</code> 放在最后的后缀。因为 <code>x != y</code>，所有 <code>y</code> 都位于这个后缀之前，所以任意 <code>y</code> 都出现在任意 <code>x</code> 的左侧。故算法返回的字符串一定合法。</p>
<h3 id="复杂度">复杂度</h3>
<ul>
<li>时间复杂度：<code>O(n)</code>；</li>
<li>空间复杂度：<code>O(n)</code>，用于构造返回字符串。</li>
</ul>
<h3 id="java-17-标程">Java 17 标程</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">class</span> <span class="nc">Solution</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">public</span><span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="nf">rearrangeString</span><span class="p">(</span><span class="n">String</span><span class="w"> </span><span class="n">s</span><span class="p">,</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="n">y</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="w"> </span><span class="n">countX</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="w"> </span><span class="n">countY</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">s</span><span class="p">.</span><span class="na">length</span><span class="p">();</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="kt">char</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">s</span><span class="p">.</span><span class="na">charAt</span><span class="p">(</span><span class="n">i</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">c</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="n">countX</span><span class="o">++</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">c</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">y</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="n">countY</span><span class="o">++</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">StringBuilder</span><span class="w"> </span><span class="n">answer</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">StringBuilder</span><span class="p">(</span><span class="n">s</span><span class="p">.</span><span class="na">length</span><span class="p">());</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">countY</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">countX</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">countY</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="n">answer</span><span class="p">.</span><span class="na">append</span><span class="p">(</span><span class="n">y</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">s</span><span class="p">.</span><span class="na">length</span><span class="p">();</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="kt">char</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">s</span><span class="p">.</span><span class="na">charAt</span><span class="p">(</span><span class="n">i</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">c</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">y</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="n">answer</span><span class="p">.</span><span class="na">append</span><span class="p">(</span><span class="n">c</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">s</span><span class="p">.</span><span class="na">length</span><span class="p">();</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="kt">char</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">s</span><span class="p">.</span><span class="na">charAt</span><span class="p">(</span><span class="n">i</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">c</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="n">answer</span><span class="p">.</span><span class="na">append</span><span class="p">(</span><span class="n">c</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">countX</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">answer</span><span class="p">.</span><span class="na">append</span><span class="p">(</span><span class="n">x</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="n">answer</span><span class="p">.</span><span class="na">toString</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="易错点">易错点</h3>
<ul>
<li>只修复一处 <code>x</code>、<code>y</code> 逆序，不能保证全部 <code>y</code> 都在全部 <code>x</code> 前；</li>
<li>第一种分支的中间段必须同时排除 <code>x</code> 和 <code>y</code>；</li>
<li><code>countY &lt; countX</code> 只是实现选择布局的条件，不是答案存在的条件；</li>
<li><code>x</code> 或 <code>y</code> 没有出现时，约束可能自动成立。</li>
</ul>
<h2 id="3993-交替数列的最大元素峰值上界与构造">3993. 交替数列的最大元素｜峰值上界与构造</h2>
<p><img alt="3993 峰值递推" loading="lazy" src="/images/posts/leetcode-biweekly-contest-187/3993.png"></p>
<h3 id="题意-1">题意</h3>
<p>给定序列长度 <code>n</code>、首项 <code>s</code> 和相邻差绝对值上限 <code>m</code>。要求序列严格上升、严格下降交替出现，求所有合法整数序列中可能出现的最大元素。</p>
<h3 id="核心观察">核心观察</h3>
<p>为了让最大值尽可能大，第一步应当向上：</p>
<ul>
<li>先向上时，第一个峰值最多为 <code>s + m</code>；</li>
<li>先向下时，<code>s</code> 本身就是第一个峰值，不会优于前者。</li>
</ul>
<p>接下来考虑连续两个峰值 <code>H</code>、<code>H'</code>，中间谷值为 <code>V</code>。由于严格下降且元素为整数：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">V &lt;= H - 1
</span></span></code></pre></div><p>下一步最多上升 <code>m</code>：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">H&#39; &lt;= V + m &lt;= H + m - 1
</span></span></code></pre></div><p>所以每经过两步，峰值最多净增 <code>m - 1</code>。</p>
<h3 id="公式">公式</h3>
<p>令：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">q = floor(n / 2)
</span></span></code></pre></div><p><code>q</code> 是下标 <code>1, 3, 5, ...</code> 上峰值的数量。第一个峰值是 <code>s + m</code>，后续 <code>q - 1</code> 个峰各增加至多 <code>m - 1</code>：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">answer = s + m + (q - 1)(m - 1)
</span></span><span class="line"><span class="cl">       = s + q(m - 1) + 1
</span></span></code></pre></div><p>当 <code>n = 1</code> 时，序列只有首项，答案为 <code>s</code>。</p>
<p>例如 <code>n = 4, s = 3, m = 5</code>：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">q = 2
</span></span><span class="line"><span class="cl">answer = 3 + 2 × (5 - 1) + 1 = 12
</span></span></code></pre></div><p>可构造序列 <code>3, 8, 7, 12</code> 达到这个值。</p>
<h3 id="正确性证明-1">正确性证明</h3>
<p>上界方面，第一个峰值不超过 <code>s + m</code>；由 <code>H' &lt;= H + m - 1</code>，其后每个峰值相对前一个峰值最多增加 <code>m - 1</code>。因此任何合法序列的最大元素都不超过公式值。</p>
<p>可达性方面，从 <code>s</code> 上升 <code>m</code> 得到第一个峰；之后每次从峰值下降 <code>1</code>，再上升 <code>m</code>。两条相邻边的差分别为 <code>1</code> 和 <code>m</code>，都不超过限制，而且严格下降、严格上升交替成立。每个新峰值恰好增加 <code>m - 1</code>，最终达到公式上界。</p>
<p>上界与构造值相同，因此公式就是答案。</p>
<h3 id="复杂度-1">复杂度</h3>
<ul>
<li>时间复杂度：<code>O(1)</code>；</li>
<li>空间复杂度：<code>O(1)</code>。</li>
</ul>
<h3 id="java-17-标程-1">Java 17 标程</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">class</span> <span class="nc">Solution</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">public</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="nf">maximumValue</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">s</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">long</span><span class="w"> </span><span class="n">peakCount</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">2L</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="o">[]</span><span class="w"> </span><span class="n">mavlorenti</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="n">s</span><span class="p">,</span><span class="w"> </span><span class="n">m</span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">mavlorenti</span><span class="o">[</span><span class="n">0</span><span class="o">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">return</span><span class="w"> </span><span class="n">mavlorenti</span><span class="o">[</span><span class="n">1</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="p">(</span><span class="kt">long</span><span class="p">)</span><span class="w"> </span><span class="n">mavlorenti</span><span class="o">[</span><span class="n">1</span><span class="o">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="o">+</span><span class="w"> </span><span class="n">peakCount</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">((</span><span class="kt">long</span><span class="p">)</span><span class="w"> </span><span class="n">mavlorenti</span><span class="o">[</span><span class="n">2</span><span class="o">]</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">1L</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="o">+</span><span class="w"> </span><span class="n">1L</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="易错点-1">易错点</h3>
<ul>
<li>相邻两个峰值的净增上限是 <code>m - 1</code>，不是 <code>m</code>；</li>
<li>第一峰应先向上取得完整的 <code>m</code> 增量；</li>
<li><code>n = 1</code> 要单独处理；</li>
<li><code>n</code> 很大，乘法和返回值必须使用 <code>long</code>。</li>
</ul>
<h2 id="3994-划分数组的最少相邻交换次数三类别逆序对">3994. 划分数组的最少相邻交换次数｜三类别逆序对</h2>
<p><img alt="3994 扫描统计逆序对" loading="lazy" src="/images/posts/leetcode-biweekly-contest-187/3994.png"></p>
<h3 id="题意-2">题意</h3>
<p>通过相邻交换把数组划分成三段：</p>
<ol>
<li>第一段元素全部小于 <code>a</code>；</li>
<li>第二段元素全部位于闭区间 <code>[a,b]</code>；</li>
<li>第三段元素全部大于 <code>b</code>。</li>
</ol>
<p>三段可以为空，求最少相邻交换次数，并对 <code>10^9 + 7</code> 取模。</p>
<h3 id="核心思路-1">核心思路</h3>
<p>具体数值只决定所属区间，可以压缩成三个类别：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">value &lt; a       → 0
</span></span><span class="line"><span class="cl">a &lt;= value &lt;= b → 1
</span></span><span class="line"><span class="cl">value &gt; b       → 2
</span></span></code></pre></div><p>目标数组的类别序列必须形如 <code>0* 1* 2*</code>，也就是非递减序列。将一个序列通过相邻交换排成非递减顺序，最少交换次数恰好等于初始逆序对数量。</p>
<p>类别只有 <code>0、1、2</code>，无需树状数组。扫描前缀时维护：</p>
<ul>
<li><code>middleCount</code>：此前类别 <code>1</code> 的数量；</li>
<li><code>largeCount</code>：此前类别 <code>2</code> 的数量。</li>
</ul>
<p>当前元素的新增贡献为：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">读到 0：middleCount + largeCount
</span></span><span class="line"><span class="cl">读到 1：largeCount
</span></span><span class="line"><span class="cl">读到 2：0
</span></span></code></pre></div><p>例如类别序列 <code>2,1,1,0</code>：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">读 2：+0，累计 0
</span></span><span class="line"><span class="cl">读 1：+1，累计 1
</span></span><span class="line"><span class="cl">读 1：+1，累计 2
</span></span><span class="line"><span class="cl">读 0：+3，累计 5
</span></span></code></pre></div><p>答案为 <code>5</code>。</p>
<h3 id="正确性证明-2">正确性证明</h3>
<p>若 <code>i &lt; j</code> 且类别 <code>c[i] &gt; c[j]</code>，那么最终非递减序列中这两个元素的相对顺序必须颠倒。两个元素只有在某次相邻交换中彼此跨越时才能改变相对顺序，因此每个初始逆序对至少需要一次交换。</p>
<p>反过来，不断交换任意相邻逆序。一次交换恰好消除一个逆序对，不会增加其他逆序；当逆序数降为零时，类别序列已经非递减。因此恰好使用初始逆序对数量的交换就能完成目标。</p>
<p>扫描时，算法对每个元素准确统计所有以它为右端点的新逆序：类别 <code>0</code> 与此前所有 <code>1、2</code> 组成逆序；类别 <code>1</code> 只与此前的 <code>2</code> 组成逆序；类别 <code>2</code> 不会成为逆序右端点。不同右端点对应的逆序集合互不重叠，所以累计值就是全部逆序对数，也就是最少交换次数。</p>
<h3 id="复杂度-2">复杂度</h3>
<ul>
<li>时间复杂度：<code>O(n)</code>；</li>
<li>辅助空间复杂度：<code>O(1)</code>。</li>
</ul>
<h3 id="java-17-标程-2">Java 17 标程</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">class</span> <span class="nc">Solution</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">public</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="nf">minAdjacentSwaps</span><span class="p">(</span><span class="kt">int</span><span class="o">[]</span><span class="w"> </span><span class="n">nums</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">b</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kd">final</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">MOD</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">1_000_000_007L</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">long</span><span class="w"> </span><span class="n">middleCount</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">long</span><span class="w"> </span><span class="n">largeCount</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">long</span><span class="w"> </span><span class="n">swaps</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="o">[]</span><span class="w"> </span><span class="n">ferlominta</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nums</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">value</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="n">ferlominta</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">value</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">a</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="n">swaps</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">middleCount</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">largeCount</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">value</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">b</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="n">swaps</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">largeCount</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="n">middleCount</span><span class="o">++</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="n">largeCount</span><span class="o">++</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="n">swaps</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">MOD</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="易错点-2">易错点</h3>
<ul>
<li><code>value == a</code> 或 <code>value == b</code> 都属于类别 <code>1</code>；</li>
<li>不能只统计相邻错序，答案是所有逆序对数量；</li>
<li>逆序对最多达到 <code>n(n-1)/2</code>，累计必须使用 <code>long</code>；</li>
<li>只在最终答案处取模，类别计数本身不能取模；</li>
<li>模拟实际交换会退化为 <code>O(n²)</code>。</li>
</ul>
<h2 id="3995-转换字符串的最小成本-iii不重叠区间-dp">3995. 转换字符串的最小成本 III｜不重叠区间 DP</h2>
<p><img alt="3995 前缀 DP 路径" loading="lazy" src="/images/posts/leetcode-biweekly-contest-187/3995.png"></p>
<h3 id="题意-3">题意</h3>
<p>给定 <code>source</code>、<code>target</code> 和若干等长规则 <code>pattern -&gt; replacement</code>。<code>pattern</code> 中的 <code>'*'</code> 可以匹配任意字符，实际规则费用等于基础费用加星号数量。一次规则覆盖的位置之后不能再被任何规则使用，求把 <code>source</code> 转成 <code>target</code> 的最小费用；不可行返回 <code>-1</code>。</p>
<h3 id="核心观察-1">核心观察</h3>
<p>“用过的位置不能再次操作”意味着规则不能在同一区间上链式转换。每条规则必须：</p>
<ol>
<li>直接匹配原始 <code>source</code> 的一段连续子串；</li>
<li>一次写出 <code>target</code> 在同一段上的最终内容。</li>
</ol>
<p>于是任意合法方案都等价于从左到右划分字符串：</p>
<ul>
<li><code>source[i] == target[i]</code> 的单个字符可以免费保留；</li>
<li>其他连续区间必须由一条规则直接完成；</li>
<li>所有分段天然互不重叠。</li>
</ul>
<h3 id="状态与转移">状态与转移</h3>
<p>定义：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">dp[i] = 完成前缀 [0,i) 的最小费用
</span></span></code></pre></div><p>初始化 <code>dp[0] = 0</code>，其他状态为无穷大。从每个可达位置 <code>i</code> 有两类转移。</p>
<p><strong>免费单字符转移</strong></p>
<p>若 <code>source[i] == target[i]</code>：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">dp[i+1] = min(dp[i+1], dp[i])
</span></span></code></pre></div><p><strong>规则区间转移</strong></p>
<p>枚举规则 <code>k</code>，长度为 <code>len[k]</code>。它可以从 <code>i</code> 使用，当且仅当：</p>
<ul>
<li><code>i + len[k] &lt;= n</code>；</li>
<li><code>pattern[k]</code> 的每个非星号字符匹配 <code>source[i+j]</code>；</li>
<li><code>replacement[k][j] == target[i+j]</code> 对整段成立。</li>
</ul>
<p>此时：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">dp[i+len[k]] = min(dp[i+len[k]], dp[i] + fullCost[k])
</span></span></code></pre></div><p>其中 <code>fullCost[k]</code> 是基础费用加模式中的星号数量。</p>
<h3 id="正确性证明-3">正确性证明</h3>
<p>先从合法操作方案构造 DP 路径。合法方案的操作区间两两不重叠，按起点排序后，从左到右遍历：没有被操作的位置必须满足 <code>source[i] == target[i]</code>，对应免费边；每个操作区间直接匹配原始 <code>source</code>，并写出对应 <code>target</code> 子串，对应一条规则边。这样得到的 DP 路径与原方案费用相同。</p>
<p>再从 DP 路径构造合法方案。免费边只保留两串相等的字符；每条规则边都验证了原始 <code>source</code> 模式和最终 <code>target</code> 替换串。路径从左到右消费首尾相接的区间，因此所有规则区间互不重叠。按路径执行这些规则后，整个字符串恰好变为 <code>target</code>，费用等于路径权重。</p>
<p>合法方案与 DP 路径可以互相转换且保持费用，因此 <code>dp[n]</code> 就是最小费用；若 <code>dp[n]</code> 不可达，则不存在合法转换方案。</p>
<h3 id="复杂度-3">复杂度</h3>
<p>设字符串长度为 <code>n</code>，规则数量为 <code>R</code>，最大规则长度为 <code>L</code>：</p>
<ul>
<li>时间复杂度：<code>O(nRL)</code>；</li>
<li>空间复杂度：<code>O(n + R)</code>。</li>
</ul>
<h3 id="java-17-标程-3">Java 17 标程</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">class</span> <span class="nc">Solution</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">public</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="nf">minCost</span><span class="p">(</span><span class="n">String</span><span class="w"> </span><span class="n">source</span><span class="p">,</span><span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="n">target</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                       </span><span class="n">java</span><span class="p">.</span><span class="na">util</span><span class="p">.</span><span class="na">List</span><span class="o">&lt;</span><span class="n">java</span><span class="p">.</span><span class="na">util</span><span class="p">.</span><span class="na">List</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;&gt;</span><span class="w"> </span><span class="n">rules</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="o">[]</span><span class="w"> </span><span class="n">costs</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">source</span><span class="p">.</span><span class="na">length</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">n</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">target</span><span class="p">.</span><span class="na">length</span><span class="p">())</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">return</span><span class="w"> </span><span class="o">-</span><span class="n">1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="w"> </span><span class="n">ruleCount</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rules</span><span class="p">.</span><span class="na">size</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">String</span><span class="o">[]</span><span class="w"> </span><span class="n">patterns</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">String</span><span class="o">[</span><span class="n">ruleCount</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">String</span><span class="o">[]</span><span class="w"> </span><span class="n">replacements</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">String</span><span class="o">[</span><span class="n">ruleCount</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="o">[]</span><span class="w"> </span><span class="n">lengths</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="kt">int</span><span class="o">[</span><span class="n">ruleCount</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="o">[]</span><span class="w"> </span><span class="n">fullCosts</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="kt">int</span><span class="o">[</span><span class="n">ruleCount</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">ruleCount</span><span class="p">;</span><span class="w"> </span><span class="o">++</span><span class="n">k</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">patterns</span><span class="o">[</span><span class="n">k</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rules</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="n">k</span><span class="p">).</span><span class="na">get</span><span class="p">(</span><span class="n">0</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">replacements</span><span class="o">[</span><span class="n">k</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rules</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="n">k</span><span class="p">).</span><span class="na">get</span><span class="p">(</span><span class="n">1</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">lengths</span><span class="o">[</span><span class="n">k</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">patterns</span><span class="o">[</span><span class="n">k</span><span class="o">]</span><span class="p">.</span><span class="na">length</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="kt">int</span><span class="w"> </span><span class="n">wildcardCount</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">lengths</span><span class="o">[</span><span class="n">k</span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="o">++</span><span class="n">j</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">patterns</span><span class="o">[</span><span class="n">k</span><span class="o">]</span><span class="p">.</span><span class="na">charAt</span><span class="p">(</span><span class="n">j</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="sc">&#39;*&#39;</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="o">++</span><span class="n">wildcardCount</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">fullCosts</span><span class="o">[</span><span class="n">k</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">costs</span><span class="o">[</span><span class="n">k</span><span class="o">]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">wildcardCount</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">Object</span><span class="o">[]</span><span class="w"> </span><span class="n">vornelipta</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">Object</span><span class="o">[]</span><span class="w"> </span><span class="p">{</span><span class="n">source</span><span class="p">,</span><span class="w"> </span><span class="n">target</span><span class="p">,</span><span class="w"> </span><span class="n">rules</span><span class="p">,</span><span class="w"> </span><span class="n">costs</span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kd">final</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">INF</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">1</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">29</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="o">[]</span><span class="w"> </span><span class="n">dp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="kt">int</span><span class="o">[</span><span class="n">n</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">1</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">n</span><span class="p">;</span><span class="w"> </span><span class="o">++</span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">dp</span><span class="o">[</span><span class="n">i</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">INF</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">dp</span><span class="o">[</span><span class="n">0</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">n</span><span class="p">;</span><span class="w"> </span><span class="o">++</span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">dp</span><span class="o">[</span><span class="n">i</span><span class="o">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">INF</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="k">continue</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">source</span><span class="p">.</span><span class="na">charAt</span><span class="p">(</span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">target</span><span class="p">.</span><span class="na">charAt</span><span class="p">(</span><span class="n">i</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="n">dp</span><span class="o">[</span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">1</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Math</span><span class="p">.</span><span class="na">min</span><span class="p">(</span><span class="n">dp</span><span class="o">[</span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">1</span><span class="o">]</span><span class="p">,</span><span class="w"> </span><span class="n">dp</span><span class="o">[</span><span class="n">i</span><span class="o">]</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">ruleCount</span><span class="p">;</span><span class="w"> </span><span class="o">++</span><span class="n">k</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="kt">int</span><span class="w"> </span><span class="n">len</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">lengths</span><span class="o">[</span><span class="n">k</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">len</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">n</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="k">continue</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="kt">boolean</span><span class="w"> </span><span class="n">matches</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">true</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">len</span><span class="p">;</span><span class="w"> </span><span class="o">++</span><span class="n">j</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="kt">char</span><span class="w"> </span><span class="n">patternChar</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">patterns</span><span class="o">[</span><span class="n">k</span><span class="o">]</span><span class="p">.</span><span class="na">charAt</span><span class="p">(</span><span class="n">j</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">patternChar</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="sc">&#39;*&#39;</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">patternChar</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">source</span><span class="p">.</span><span class="na">charAt</span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">j</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                        </span><span class="n">matches</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">false</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                        </span><span class="k">break</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">replacements</span><span class="o">[</span><span class="n">k</span><span class="o">]</span><span class="p">.</span><span class="na">charAt</span><span class="p">(</span><span class="n">j</span><span class="p">)</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">target</span><span class="p">.</span><span class="na">charAt</span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">j</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                        </span><span class="n">matches</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">false</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                        </span><span class="k">break</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">matches</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="n">dp</span><span class="o">[</span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">len</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Math</span><span class="p">.</span><span class="na">min</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                        </span><span class="n">dp</span><span class="o">[</span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">len</span><span class="o">]</span><span class="p">,</span><span class="w"> </span><span class="n">dp</span><span class="o">[</span><span class="n">i</span><span class="o">]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">fullCosts</span><span class="o">[</span><span class="n">k</span><span class="o">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="n">dp</span><span class="o">[</span><span class="n">n</span><span class="o">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">INF</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="o">-</span><span class="n">1</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="n">dp</span><span class="o">[</span><span class="n">n</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="易错点-3">易错点</h3>
<ul>
<li>规则不能在同一位置连续施加；</li>
<li>除了检查 <code>pattern</code> 对 <code>source</code> 的匹配，还必须检查 <code>replacement</code> 是否等于目标子串；</li>
<li>两串相同字符可以使用零费用单字符转移；</li>
<li>星号费用按模式中的 <code>'*'</code> 数量计算；</li>
<li>局部选择最便宜或最长规则不保证全局最优，必须使用 DP；</li>
<li><code>source</code> 与 <code>target</code> 长度不同时直接返回 <code>-1</code>。</li>
</ul>
<h2 id="总结">总结</h2>
<p>本场四题可以归纳为四个很有迁移价值的建模动作：</p>
<ol>
<li><strong>只保留真正受约束的相对顺序</strong>：字符串排列题不需要搜索，把字符分桶后直接构造；</li>
<li><strong>研究局部极值之间的净变化</strong>：峰、谷、峰三点给出 <code>m-1</code> 的增长上界，再用同样结构达到上界；</li>
<li><strong>相邻交换排序等价于消除逆序对</strong>：类别很少时，用常数个计数器即可在线统计；</li>
<li><strong>不重叠操作天然对应前缀分段</strong>：把免费位置和规则区间都视作 DP 边，就能统一求最小成本。</li>
</ol>
<p>四题看起来分别属于构造、数学、计数与动态规划，但核心都在于删去无关细节，把题目压缩成最小状态。比记住具体代码更重要的是识别这种“分桶、局部上界、逆序、前缀分段”的转换。</p>
]]></content:encoded></item><item><title>力扣周赛 512 题解：贪心、双指针、组合计数与分层 Dijkstra</title><link>https://blog.weiuou.top/posts/leetcode-weekly-contest-512-editorial/</link><pubDate>Mon, 27 Jul 2026 01:20:44 +0800</pubDate><guid>https://blog.weiuou.top/posts/leetcode-weekly-contest-512-editorial/</guid><description>力扣第 512 场周赛四题完整题解：从高位贪心、时间序列双指针，到补集组合计数与带奇偶状态的 Dijkstra，附 Java 17 标程、正确性证明和 Accepted 记录。</description><content:encoded><![CDATA[<p>这篇文章整理力扣中文站第 512 场周赛的四道题。四份 Java 17 代码都经过本地编译、样例与边界测试，并已在力扣获得 <code>Accepted</code>。</p>
<p>本场四题的思维跨度很有代表性：第一题从最高位做贪心，第二题用双指针维护“第一个不小于当前时间”的元素，第三题把“乘积为偶数”转成补集计数，第四题则必须把行动奇偶性并入最短路状态。</p>
<h2 id="题目总览">题目总览</h2>
<table>
	<thead>
			<tr>
					<th>题号</th>
					<th>题目</th>
					<th>核心方法</th>
					<th>时间复杂度</th>
					<th>Accepted 提交</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>4000</td>
					<td><a href="https://leetcode.cn/problems/largest-integer-with-given-digit-sum/">给定数位和的最大整数</a></td>
					<td>高位贪心</td>
					<td><code>O(n)</code></td>
					<td><code>738213138</code></td>
			</tr>
			<tr>
					<td>4001</td>
					<td><a href="https://leetcode.cn/problems/aggregate-two-time-series/">聚合两个时间序列</a></td>
					<td>双指针归并</td>
					<td><code>O(n + m)</code></td>
					<td><code>738224005</code></td>
			</tr>
			<tr>
					<td>4002</td>
					<td><a href="https://leetcode.cn/problems/count-valid-sequences/">统计有效序列数目</a></td>
					<td>补集计数、组合数学</td>
					<td><code>O(n + log MOD)</code></td>
					<td><code>738213380</code></td>
			</tr>
			<tr>
					<td>4003</td>
					<td><a href="https://leetcode.cn/problems/minimum-cost-path-with-alternating-directions-iii/">交替方向的最小路径代价 III</a></td>
					<td>分层图、Dijkstra</td>
					<td><code>O(mn log(mn))</code></td>
					<td><code>738224023</code></td>
			</tr>
	</tbody>
</table>
<h2 id="4000-给定数位和的最大整数">4000. 给定数位和的最大整数</h2>
<p><img alt="给定数位和的最大整数" loading="lazy" src="/images/posts/leetcode-weekly-contest-512/4000-cover.png"></p>
<p>给定非负整数 <code>n</code> 和 <code>s</code>，求一个至多有 <code>n</code> 位、各位数字之和为 <code>s</code> 的最大整数；若不存在则返回 <code>-1</code>。</p>
<h3 id="核心思路">核心思路</h3>
<p>把不足 <code>n</code> 位的整数在左侧补零，它的数值和数位和都不会改变。问题于是等价于：构造一个字典序最大的、长度恰好为 <code>n</code> 的数位串。</p>
<p>每一位最多贡献 <code>9</code>，所以首先要检查可行性：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">s &lt;= 9n
</span></span></code></pre></div><p>可行时，从最高位开始，把剩余数位和尽可能多地放在当前位：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">digit = min(9, remaining)
</span></span></code></pre></div><p>例如 <code>n = 3, s = 20</code>，依次填入 <code>9、9、2</code>，答案为 <code>992</code>。</p>
<h3 id="正确性证明">正确性证明</h3>
<p>若 <code>s &gt; 9n</code>，<code>n</code> 个数位能提供的数位和至多为 <code>9n</code>，因此必然无解。</p>
<p>下面考虑 <code>s &lt;= 9n</code>。设当前还剩 <code>r</code> 的数位和、包括当前位在内还剩 <code>k</code> 位，算法选择 <code>d = min(9, r)</code>：</p>
<ul>
<li>若 <code>r &lt;= 9</code>，当前位填 <code>r</code>，其余位填 <code>0</code>，一定可以完成；</li>
<li>若 <code>r &gt; 9</code>，当前位填 <code>9</code>。由此前状态可行可知 <code>r &lt;= 9k</code>，于是 <code>r - 9 &lt;= 9(k - 1)</code>，剩余位置仍能容纳余下的数位和。</li>
</ul>
<p>任何可行方案的当前位都不可能超过 <code>min(9, r)</code>。因此算法在每个位置都选择了不破坏可行性的最大数位，使前缀字典序最大。逐位应用这一结论，最终构造出的就是数值最大的可行整数。</p>
<h3 id="复杂度">复杂度</h3>
<ul>
<li>时间复杂度：<code>O(n)</code>；</li>
<li>空间复杂度：<code>O(1)</code>。</li>
</ul>
<h3 id="java-17-标程">Java 17 标程</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">class</span> <span class="nc">Solution</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">public</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="nf">largestInteger</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">s</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">s</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">9</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">return</span><span class="w"> </span><span class="o">-</span><span class="n">1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="w"> </span><span class="n">answer</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="w"> </span><span class="n">remaining</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">s</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">n</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="kt">int</span><span class="w"> </span><span class="n">digit</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Math</span><span class="p">.</span><span class="na">min</span><span class="p">(</span><span class="n">9</span><span class="p">,</span><span class="w"> </span><span class="n">remaining</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">answer</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">answer</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">10</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">digit</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">remaining</span><span class="w"> </span><span class="o">-=</span><span class="w"> </span><span class="n">digit</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="n">answer</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="易错点">易错点</h3>
<ul>
<li>真正的可行条件是 <code>s &lt;= 9n</code>，不能只看 <code>s</code> 的全局上限；</li>
<li>大数位应优先放在高位，而不是低位；</li>
<li><code>s = 0</code> 时答案是 <code>0</code>，不是 <code>-1</code>；</li>
<li>“至多 <code>n</code> 位”可以通过左侧补零统一成“恰好 <code>n</code> 位”。</li>
</ul>
<h2 id="4001-聚合两个时间序列">4001. 聚合两个时间序列</h2>
<p><img alt="聚合两个时间序列" loading="lazy" src="/images/posts/leetcode-weekly-contest-512/4001-cover.png"></p>
<p>给定两个按时间戳严格递增的序列。对于两个序列中出现过的每个时间戳 <code>t</code>：</p>
<ul>
<li>某个序列含有 <code>t</code>，就取它在 <code>t</code> 的值；</li>
<li>不含 <code>t</code>，但存在更晚时间戳，就取最早的更晚项的值；</li>
<li>不存在不早于 <code>t</code> 的项，则取 <code>0</code>。</li>
</ul>
<p>返回两个序列贡献之和，并按时间戳严格递增排列。</p>
<h3 id="核心思路-1">核心思路</h3>
<p>时间戳可以很大，答案却只会出现在两个输入序列已有的时间戳上，因此不应枚举完整时间轴。</p>
<p>用 <code>i</code>、<code>j</code> 分别指向两个序列尚未消费的第一项。每轮取两指针时间戳中的较小值作为当前输出时间 <code>t</code>。由于输出时间单调递增，某个序列的当前指针始终是该序列中第一个时间戳不小于 <code>t</code> 的元素：</p>
<ul>
<li>指针时间等于 <code>t</code>，它就是显式值；</li>
<li>指针时间大于 <code>t</code>，它正好是题目要求的“最早的更晚项”；</li>
<li>指针越界，说明贡献为 <code>0</code>。</li>
</ul>
<p>输出结果后，只推进时间戳恰好等于 <code>t</code> 的指针。不能推进另一个指针，因为它仍要为更早的缺失时间戳提供向后取值。</p>
<h3 id="正确性证明-1">正确性证明</h3>
<p>维护如下循环不变式：</p>
<ol>
<li>所有小于下一次输出时间戳的并集时间戳，都已经恰好输出一次；</li>
<li><code>i</code>、<code>j</code> 分别指向对应序列尚未消费的第一项。</li>
</ol>
<p>令 <code>t</code> 为两个未耗尽指针时间戳中的较小者，它一定是尚未处理的最小并集时间戳。对任意未耗尽的序列，其当前指针不可能小于 <code>t</code>，否则还存在一个更小但未输出的时间戳。因此当前指针就是该序列第一个不小于 <code>t</code> 的元素，按等于、大于或越界三种情况取得的贡献都符合题意。</p>
<p>输出 <code>t</code> 后，算法只消费时间戳等于 <code>t</code> 的输入项，不会跳过后续候选，于是循环不变式重新成立。每轮至少有一个指针前进，循环最终结束；此时所有并集时间戳都按严格递增顺序恰好输出一次，且每项的和值正确。</p>
<h3 id="复杂度-1">复杂度</h3>
<p>设两序列长度分别为 <code>n</code>、<code>m</code>，不同时间戳的总数为 <code>k</code>：</p>
<ul>
<li>时间复杂度：<code>O(n + m)</code>；</li>
<li>返回结果占 <code>O(k)</code> 空间，除此之外的辅助空间为 <code>O(1)</code>。</li>
</ul>
<h3 id="java-17-标程-1">Java 17 标程</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">class</span> <span class="nc">Solution</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">public</span><span class="w"> </span><span class="n">java</span><span class="p">.</span><span class="na">util</span><span class="p">.</span><span class="na">List</span><span class="o">&lt;</span><span class="n">java</span><span class="p">.</span><span class="na">util</span><span class="p">.</span><span class="na">List</span><span class="o">&lt;</span><span class="n">Integer</span><span class="o">&gt;&gt;</span><span class="w"> </span><span class="nf">aggregateTimeSeries</span><span class="p">(</span><span class="kt">int</span><span class="o">[][]</span><span class="w"> </span><span class="n">series1</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="o">[][]</span><span class="w"> </span><span class="n">series2</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">series1</span><span class="p">.</span><span class="na">length</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">series2</span><span class="p">.</span><span class="na">length</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">java</span><span class="p">.</span><span class="na">util</span><span class="p">.</span><span class="na">List</span><span class="o">&lt;</span><span class="n">java</span><span class="p">.</span><span class="na">util</span><span class="p">.</span><span class="na">List</span><span class="o">&lt;</span><span class="n">Integer</span><span class="o">&gt;&gt;</span><span class="w"> </span><span class="n">result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">java</span><span class="p">.</span><span class="na">util</span><span class="p">.</span><span class="na">ArrayList</span><span class="o">&lt;&gt;</span><span class="p">(</span><span class="n">n</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">m</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="o">[][][]</span><span class="w"> </span><span class="n">ferilonsar</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="n">series1</span><span class="p">,</span><span class="w"> </span><span class="n">series2</span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="o">[][]</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ferilonsar</span><span class="o">[</span><span class="n">0</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="o">[][]</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ferilonsar</span><span class="o">[</span><span class="n">1</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="kt">int</span><span class="w"> </span><span class="n">timestamp</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="p">(</span><span class="n">j</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">a</span><span class="o">[</span><span class="n">i</span><span class="o">][</span><span class="n">0</span><span class="o">]</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">b</span><span class="o">[</span><span class="n">j</span><span class="o">][</span><span class="n">0</span><span class="o">]</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="n">timestamp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">a</span><span class="o">[</span><span class="n">i</span><span class="o">][</span><span class="n">0</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="n">timestamp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">b</span><span class="o">[</span><span class="n">j</span><span class="o">][</span><span class="n">0</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="kt">int</span><span class="w"> </span><span class="n">value1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="n">a</span><span class="o">[</span><span class="n">i</span><span class="o">][</span><span class="n">1</span><span class="o">]</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="kt">int</span><span class="w"> </span><span class="n">value2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="n">b</span><span class="o">[</span><span class="n">j</span><span class="o">][</span><span class="n">1</span><span class="o">]</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">result</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="n">java</span><span class="p">.</span><span class="na">util</span><span class="p">.</span><span class="na">List</span><span class="p">.</span><span class="na">of</span><span class="p">(</span><span class="n">timestamp</span><span class="p">,</span><span class="w"> </span><span class="n">value1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">value2</span><span class="p">));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">a</span><span class="o">[</span><span class="n">i</span><span class="o">][</span><span class="n">0</span><span class="o">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">timestamp</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="n">i</span><span class="o">++</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">j</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">b</span><span class="o">[</span><span class="n">j</span><span class="o">][</span><span class="n">0</span><span class="o">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">timestamp</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="n">j</span><span class="o">++</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="n">result</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="易错点-1">易错点</h3>
<ul>
<li>缺失时间戳取的是下一个更晚值，不是前一个值；</li>
<li>另一个指针尚未到当前时间戳时，不能提前推进；</li>
<li>两个序列时间戳相同时只能输出一次，并同时推进两个指针；</li>
<li>不要枚举最大可达 <code>10^9</code> 的完整时间轴。</li>
</ul>
<h2 id="4002-统计有效序列数目">4002. 统计有效序列数目</h2>
<p><img alt="统计有效序列数目" loading="lazy" src="/images/posts/leetcode-weekly-contest-512/4002-cover.png"></p>
<p>统计长度为 <code>k</code> 的正整数有序序列：所有元素之和为 <code>n</code>，且元素乘积为偶数。答案对 <code>10^9 + 7</code> 取模。</p>
<h3 id="核心思路-2">核心思路</h3>
<p>乘积为偶数，等价于序列中至少有一个偶数。直接枚举偶数位置会发生大量重叠，最自然的做法是计算补集：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">有效序列 = 所有正整数序列 - 所有元素均为奇数的序列
</span></span></code></pre></div><p>先看所有正整数序列。把 <code>n</code> 个单位用 <code>k - 1</code> 块隔板切成 <code>k</code> 个非空部分，由隔板法得到：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">A = C(n - 1, k - 1)
</span></span></code></pre></div><p>再统计全奇数序列。令：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">x_i = 2y_i + 1,  y_i &gt;= 0
</span></span></code></pre></div><p>代入 <code>x_1 + ... + x_k = n</code>：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">y_1 + ... + y_k = (n - k) / 2
</span></span></code></pre></div><p>若 <code>n - k</code> 为奇数，右侧不是整数，全奇数序列数为 <code>0</code>。否则再次使用隔板法：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">B = C((n - k) / 2 + k - 1, k - 1)
</span></span><span class="line"><span class="cl">  = C((n + k - 2) / 2, k - 1)
</span></span></code></pre></div><p>最终答案为：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">(A - B + MOD) % MOD
</span></span></code></pre></div><p>代码预处理阶乘和逆阶乘，再用费马小定理求逆元，使每次组合数查询为 <code>O(1)</code>。</p>
<h3 id="正确性证明-2">正确性证明</h3>
<p>所有满足条件的正整数序列共有 <code>C(n - 1, k - 1)</code> 个。一个整数乘积为奇数，当且仅当每个因子都是奇数，因此不合法的序列恰好是全奇数序列。</p>
<p>对于任意全奇数序列，每一项都能唯一写成 <code>x_i = 2y_i + 1</code>，其中 <code>y_i &gt;= 0</code>。这与和为 <code>(n-k)/2</code> 的 <code>k</code> 个非负整数序列构成一一对应：</p>
<ul>
<li>当 <code>n-k</code> 为奇数时不存在这样的整数序列；</li>
<li>当 <code>n-k</code> 为偶数时，隔板法给出 <code>C((n+k-2)/2, k-1)</code> 个方案。</li>
</ul>
<p>从所有正整数序列中去掉全部全奇数序列，剩余序列至少包含一个偶数，其乘积必为偶数；反之每个乘积为偶数的序列也都保留。因此算法计算的差正好是题目要求的答案。</p>
<h3 id="复杂度-2">复杂度</h3>
<ul>
<li>时间复杂度：<code>O(n + log MOD)</code>，其中快速幂只执行一次；</li>
<li>空间复杂度：<code>O(n)</code>，用于阶乘和逆阶乘数组。</li>
</ul>
<h3 id="java-17-标程-2">Java 17 标程</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">class</span> <span class="nc">Solution</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">MOD</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">1_000_000_007L</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">public</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="nf">countValidSequences</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">k</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="w"> </span><span class="n">limit</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">long</span><span class="o">[]</span><span class="w"> </span><span class="n">fact</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="kt">long</span><span class="o">[</span><span class="n">limit</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">1</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">long</span><span class="o">[]</span><span class="w"> </span><span class="n">invFact</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="kt">long</span><span class="o">[</span><span class="n">limit</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">1</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="o">[]</span><span class="w"> </span><span class="n">ravolqedin</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="kt">int</span><span class="o">[]</span><span class="w"> </span><span class="p">{</span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="n">k</span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">fact</span><span class="o">[</span><span class="n">0</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">1</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">limit</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">fact</span><span class="o">[</span><span class="n">i</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">fact</span><span class="o">[</span><span class="n">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">1</span><span class="o">]</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">MOD</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">invFact</span><span class="o">[</span><span class="n">limit</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">modPow</span><span class="p">(</span><span class="n">fact</span><span class="o">[</span><span class="n">limit</span><span class="o">]</span><span class="p">,</span><span class="w"> </span><span class="n">MOD</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">2</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">limit</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">1</span><span class="p">;</span><span class="w"> </span><span class="n">i</span><span class="o">--</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">invFact</span><span class="o">[</span><span class="n">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">1</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">invFact</span><span class="o">[</span><span class="n">i</span><span class="o">]</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">MOD</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="w"> </span><span class="n">storedN</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ravolqedin</span><span class="o">[</span><span class="n">0</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="w"> </span><span class="n">storedK</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ravolqedin</span><span class="o">[</span><span class="n">1</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">long</span><span class="w"> </span><span class="n">total</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">choose</span><span class="p">(</span><span class="n">storedN</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">1</span><span class="p">,</span><span class="w"> </span><span class="n">storedK</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">1</span><span class="p">,</span><span class="w"> </span><span class="n">fact</span><span class="p">,</span><span class="w"> </span><span class="n">invFact</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">long</span><span class="w"> </span><span class="n">allOdd</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="p">(((</span><span class="n">storedN</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">storedK</span><span class="p">)</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="n">1</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="kt">int</span><span class="w"> </span><span class="n">oddTop</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">storedN</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">storedK</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">2</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">2</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">allOdd</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">choose</span><span class="p">(</span><span class="n">oddTop</span><span class="p">,</span><span class="w"> </span><span class="n">storedK</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">1</span><span class="p">,</span><span class="w"> </span><span class="n">fact</span><span class="p">,</span><span class="w"> </span><span class="n">invFact</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">((</span><span class="n">total</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">allOdd</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">MOD</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">MOD</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">private</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="nf">choose</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">r</span><span class="p">,</span><span class="w"> </span><span class="kt">long</span><span class="o">[]</span><span class="w"> </span><span class="n">fact</span><span class="p">,</span><span class="w"> </span><span class="kt">long</span><span class="o">[]</span><span class="w"> </span><span class="n">invFact</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">r</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">0</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">n</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">return</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="n">fact</span><span class="o">[</span><span class="n">n</span><span class="o">]</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">invFact</span><span class="o">[</span><span class="n">r</span><span class="o">]</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">MOD</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">invFact</span><span class="o">[</span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">r</span><span class="o">]</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">MOD</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">private</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="nf">modPow</span><span class="p">(</span><span class="kt">long</span><span class="w"> </span><span class="n">base</span><span class="p">,</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="n">exponent</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">long</span><span class="w"> </span><span class="n">result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">exponent</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">if</span><span class="w"> </span><span class="p">((</span><span class="n">exponent</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="n">1</span><span class="p">)</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="n">result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">result</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">base</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">MOD</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">base</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">base</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">base</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">MOD</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">exponent</span><span class="w"> </span><span class="o">&gt;&gt;=</span><span class="w"> </span><span class="n">1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="n">result</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="易错点-2">易错点</h3>
<ul>
<li>题目统计的是有序序列，不是无序整数划分；</li>
<li>正整数有序分拆总数是 <code>C(n - 1, k - 1)</code>，不是 <code>C(n, k)</code>；</li>
<li>计算全奇数序列前必须判断 <code>n - k</code> 的奇偶性；</li>
<li>模减法要先加 <code>MOD</code>，组合数乘法要使用 <code>long</code>。</li>
</ul>
<h2 id="4003-交替方向的最小路径代价-iii">4003. 交替方向的最小路径代价 III</h2>
<p><img alt="交替方向的最小路径代价 III" loading="lazy" src="/images/posts/leetcode-weekly-contest-512/4003-cover.png"></p>
<p>从 <code>(0, 0)</code> 出发并先支付其入口代价，到达 <code>(m - 1, n - 1)</code>：</p>
<ul>
<li>第奇数次行动偏好向右或向下；</li>
<li>第偶数次行动偏好向左或向上；</li>
<li>反向移动仍然允许，但要额外支付来源格的惩罚；</li>
<li>也可以原地等待，并支付当前格惩罚；</li>
<li>每次移动或等待后，行动奇偶性都会翻转。</li>
</ul>
<p>求到达终点的最小总成本。</p>
<h3 id="核心思路-3">核心思路</h3>
<p>同一个格子在不同的行动奇偶性下，下一步的优先方向不同，所以“只记录坐标”是不充分的。把每个格子拆成两个状态：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">(r, c, p)
</span></span></code></pre></div><p>其中 <code>p = 0</code> 表示下一步是奇数次行动，<code>p = 1</code> 表示下一步是偶数次行动。</p>
<p>从每个状态连出两类边：</p>
<ol>
<li><strong>等待边</strong>：留在原格，增加 <code>penalty[r][c]</code>；</li>
<li><strong>移动边</strong>：走到相邻格，支付目标格入口代价 <code>(nr + 1) * (nc + 1)</code>；若方向不受当前奇偶性偏好，再加来源格 <code>penalty[r][c]</code>。</li>
</ol>
<p>无论等待还是移动，下一状态的奇偶性都是 <code>p xor 1</code>。</p>
<p>这个隐式图有 <code>2mn</code> 个节点，每个节点至多五条出边。边权都非负，但等待和四向移动会形成环，因此应在分层状态图上运行 Dijkstra，而不是写单调网格 DP。</p>
<h3 id="正确性证明-3">正确性证明</h3>
<p>定义状态 <code>(r, c, p)</code> 为：当前位于 <code>(r, c)</code>，下一次行动的奇偶性为 <code>p</code>。</p>
<p>同一个格子在不同 <code>p</code> 下允许的优先方向不同，后续最优代价可能不同，因此两种状态不能合并。</p>
<p>算法从每个状态恰好连出所有合法行动：</p>
<ul>
<li>等待边的代价是当前格惩罚；</li>
<li>移动边包含目标格入口代价，并在方向不受偏好时加入来源格惩罚；</li>
<li>每条边都翻转行动奇偶性。</li>
</ul>
<p>因此，任意合法行动序列都唯一对应状态图中的一条路径，且路径权重等于行动总成本；反过来，图中的每条路径也对应一个合法行动序列。</p>
<p>初始距离设为状态 <code>(0, 0, 0)</code> 的 <code>1</code>，恰好支付起点入口代价。由于所有边权非负，Dijkstra 能求出每个状态的最短距离。终点可能在任意一种奇偶状态下到达，取两者距离的较小值，就得到全体合法行动序列中的最小成本。</p>
<h3 id="复杂度-3">复杂度</h3>
<ul>
<li>时间复杂度：<code>O(mn log(mn))</code>；</li>
<li>空间复杂度：<code>O(mn)</code>。</li>
</ul>
<h3 id="java-17-标程-3">Java 17 标程</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kd">class</span> <span class="nc">Solution</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">public</span><span class="w"> </span><span class="kt">long</span><span class="w"> </span><span class="nf">minCost</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">m</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="o">[][]</span><span class="w"> </span><span class="n">penalty</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="w"> </span><span class="n">cells</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">long</span><span class="o">[]</span><span class="w"> </span><span class="n">dist</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="kt">long</span><span class="o">[</span><span class="n">cells</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">2</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">java</span><span class="p">.</span><span class="na">util</span><span class="p">.</span><span class="na">Arrays</span><span class="p">.</span><span class="na">fill</span><span class="p">(</span><span class="n">dist</span><span class="p">,</span><span class="w"> </span><span class="n">Long</span><span class="p">.</span><span class="na">MAX_VALUE</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="o">[][]</span><span class="w"> </span><span class="n">qavirelmon</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">penalty</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">java</span><span class="p">.</span><span class="na">util</span><span class="p">.</span><span class="na">PriorityQueue</span><span class="o">&lt;</span><span class="kt">long</span><span class="o">[]&gt;</span><span class="w"> </span><span class="n">pq</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">java</span><span class="p">.</span><span class="na">util</span><span class="p">.</span><span class="na">PriorityQueue</span><span class="o">&lt;&gt;</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">)</span><span class="w"> </span><span class="o">-&gt;</span><span class="w"> </span><span class="n">Long</span><span class="p">.</span><span class="na">compare</span><span class="p">(</span><span class="n">a</span><span class="o">[</span><span class="n">0</span><span class="o">]</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="o">[</span><span class="n">0</span><span class="o">]</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">dist</span><span class="o">[</span><span class="n">0</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">1L</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">pq</span><span class="p">.</span><span class="na">offer</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="kt">long</span><span class="o">[]</span><span class="w"> </span><span class="p">{</span><span class="n">1L</span><span class="p">,</span><span class="w"> </span><span class="n">0L</span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="o">[]</span><span class="w"> </span><span class="n">dr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="o">-</span><span class="n">1</span><span class="p">,</span><span class="w"> </span><span class="n">1</span><span class="p">,</span><span class="w"> </span><span class="n">0</span><span class="p">,</span><span class="w"> </span><span class="n">0</span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="o">[]</span><span class="w"> </span><span class="n">dc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="n">0</span><span class="p">,</span><span class="w"> </span><span class="n">0</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="n">1</span><span class="p">,</span><span class="w"> </span><span class="n">1</span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">pq</span><span class="p">.</span><span class="na">isEmpty</span><span class="p">())</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="kt">long</span><span class="o">[]</span><span class="w"> </span><span class="n">current</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pq</span><span class="p">.</span><span class="na">poll</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="kt">long</span><span class="w"> </span><span class="n">cost</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">current</span><span class="o">[</span><span class="n">0</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="kt">int</span><span class="w"> </span><span class="n">state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="n">current</span><span class="o">[</span><span class="n">1</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">cost</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">dist</span><span class="o">[</span><span class="n">state</span><span class="o">]</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="k">continue</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="kt">int</span><span class="w"> </span><span class="n">parity</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">state</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="n">1</span><span class="p">;</span><span class="w"> </span><span class="c1">// 0: odd action next, 1: even action next</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="kt">int</span><span class="w"> </span><span class="n">cell</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">state</span><span class="w"> </span><span class="o">&gt;&gt;</span><span class="w"> </span><span class="n">1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="kt">int</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cell</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">n</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="kt">int</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cell</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">n</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="kt">int</span><span class="w"> </span><span class="n">waitState</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">state</span><span class="w"> </span><span class="o">^</span><span class="w"> </span><span class="n">1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="kt">long</span><span class="w"> </span><span class="n">waitCost</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cost</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">qavirelmon</span><span class="o">[</span><span class="n">r</span><span class="o">][</span><span class="n">c</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">waitCost</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">dist</span><span class="o">[</span><span class="n">waitState</span><span class="o">]</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="n">dist</span><span class="o">[</span><span class="n">waitState</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">waitCost</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="n">pq</span><span class="p">.</span><span class="na">offer</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="kt">long</span><span class="o">[]</span><span class="w"> </span><span class="p">{</span><span class="n">waitCost</span><span class="p">,</span><span class="w"> </span><span class="n">waitState</span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">0</span><span class="p">;</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">4</span><span class="p">;</span><span class="w"> </span><span class="n">k</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="kt">int</span><span class="w"> </span><span class="n">nr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">r</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">dr</span><span class="o">[</span><span class="n">k</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="kt">int</span><span class="w"> </span><span class="n">nc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">dc</span><span class="o">[</span><span class="n">k</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">nr</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">0</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">nr</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">m</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">nc</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">0</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">nc</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">n</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="k">continue</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="kt">boolean</span><span class="w"> </span><span class="n">preferred</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">parity</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="n">preferred</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">dr</span><span class="o">[</span><span class="n">k</span><span class="o">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">1</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">dc</span><span class="o">[</span><span class="n">k</span><span class="o">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="n">preferred</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">dr</span><span class="o">[</span><span class="n">k</span><span class="o">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="o">-</span><span class="n">1</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">dc</span><span class="o">[</span><span class="n">k</span><span class="o">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="o">-</span><span class="n">1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="kt">long</span><span class="w"> </span><span class="n">nextCost</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cost</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="kt">long</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="n">nr</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">1</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="n">nc</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">1</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">preferred</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="n">nextCost</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">qavirelmon</span><span class="o">[</span><span class="n">r</span><span class="o">][</span><span class="n">c</span><span class="o">]</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="kt">int</span><span class="w"> </span><span class="n">nextCell</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nr</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">nc</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="kt">int</span><span class="w"> </span><span class="n">nextState</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">nextCell</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">1</span><span class="p">)</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="p">(</span><span class="n">parity</span><span class="w"> </span><span class="o">^</span><span class="w"> </span><span class="n">1</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">nextCost</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">dist</span><span class="o">[</span><span class="n">nextState</span><span class="o">]</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="n">dist</span><span class="o">[</span><span class="n">nextState</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nextCost</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                    </span><span class="n">pq</span><span class="p">.</span><span class="na">offer</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="kt">long</span><span class="o">[]</span><span class="w"> </span><span class="p">{</span><span class="n">nextCost</span><span class="p">,</span><span class="w"> </span><span class="n">nextState</span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="kt">int</span><span class="w"> </span><span class="n">targetState</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">cells</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">1</span><span class="p">)</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="n">Math</span><span class="p">.</span><span class="na">min</span><span class="p">(</span><span class="n">dist</span><span class="o">[</span><span class="n">targetState</span><span class="o">]</span><span class="p">,</span><span class="w"> </span><span class="n">dist</span><span class="o">[</span><span class="n">targetState</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">1</span><span class="o">]</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="易错点-3">易错点</h3>
<ul>
<li>只记录单元格，不记录下一次行动的奇偶性；</li>
<li>把非偏好方向误当成不能走；它仍然可走，只是要增加来源格惩罚；</li>
<li>给非偏好移动误加目标格惩罚，或者等待后忘记翻转奇偶性；</li>
<li>漏掉起点 <code>(0, 0)</code> 的入口代价 <code>1</code>；</li>
<li>把存在四向移动和等待环的本题写成单调网格 DP；</li>
<li>入口代价乘法没有先转为 <code>long</code>。</li>
</ul>
<h2 id="总结">总结</h2>
<p>本场四题可以归纳为四个常用的建模动作：</p>
<ol>
<li><strong>最大化数值时优先确定高位</strong>：把“至多 <code>n</code> 位”补零为固定长度，就能直接按字典序贪心；</li>
<li><strong>有序流上的“下一个元素”由未消费指针自然表示</strong>：双指针不只用于求交并，也能维护 successor；</li>
<li><strong>“至少一个”常适合转为补集</strong>：乘积为偶数的反面是全奇数，随后用变量代换接上隔板法；</li>
<li><strong>未来规则依赖历史奇偶性时扩展状态</strong>：把行动奇偶性放进节点，就能把复杂过程还原为普通非负权最短路。</li>
</ol>
<p>四份代码对应的提交均已通过力扣判题。做完题后再从“贪心顺序、指针语义、补集、一层额外状态”这四个角度复盘，会比只记住具体代码更有迁移价值。</p>
]]></content:encoded></item></channel></rss>