HDU 5350 MZL's munhaff function 题解

Statement

给长度为 \(n\) 的单调不上升序列 \(A\)\(B\) 为 \(A\) 的后缀和。你最开始在 \((n,1)\),要花费最小的代价跳到 \((1,1)\)。当你在 \((x,y)\) 时有两种选项:不花费任何代价跳到 \((x-1,y+1)\),或是花费 \(B_x\) 的代价跳到 \((x,\lceil\frac{y}{2}\rceil)\)

\(n,A_i\le 10^6\)

Solution

神仙题,不看标题猜不出一点,猜出来证不了一点

维护一个堆,开始让 \(A\) 中所有元素入堆,每次选堆中最小的两个数 \(a,b\),把 \(a+b\) 累加进答案,并把 \(a+b\) 加入堆。其实就是做一个最小哈夫曼树,也是最简单的“合并果子”。

证明:

首先

\[ f(i,j)=\begin{cases} 0&(i,j)=(1,1)\\ \min(f(i-1,j+1),f(i,\lceil\frac j2\rceil)+B_i)&i,j\in[1..n],(i,j)\not=(1,1)\\ \inf&\text{otherwise} \end{cases} \]

\[ Ans=f(n,1) \]

在哈夫曼树中,每个叶节点会在它的所有祖先中贡献一次权值,那么在最小哈夫曼树中,深度较深的叶节点一定设置着权值较小的 \(A_i\)。给定的 \(A_i\) 已经预先排成降序,即 \(A_i\) 是第 \(i\) 大的叶节点。

考虑一个问题:所有 \(A\) 组成的哈夫曼树中代价最小是多少。代价定义为这棵树所有节点权值之和。

假装我们不会贪心,考虑 DP。

为了确定出一棵哈夫曼树的代价,我们只需确定每个叶子的深度,又因为 \(A_i\) 降序排列,故 \(A_i\) 的深度单调递增,根据整数划分数 trick 我们可以通过两种操作唯一地确定出深度序列,与每种代价一一对应:

  • \(A_i\) 放置在第一个空叶节点处。
  • 把所有空叶节点的深度 \(+1\),这时空叶节点数翻倍。

于是就可以做了!设 \(g(i,j)\) 表示,现在正在决策 \(A_i\) 的位置,现在共有 \(j\) 个空叶节点的最小代价。有两种可能:

  • 我们可以给 \(A_i\) 分配一个空叶节点,\(g(i,j)\to g(i+1,j-1)\)
  • 还可以给所有 \(j\) 个空叶节点分配两个儿子,空叶节点数翻倍,\(g(i,j)\to g(i,2j)\)

其中第二种操作会增加 \(\sum_{p\in[i..n]}A_p=B_i\) 的代价。初值为 \(g(1,1)=0\),答案为 \(g(n,1)\)

发现这个转移和上面 \(f\) 的转移一模一样!!!然后我们马上又会贪心了,于是做完了。

不过 \(j\) 不是偶数时 \(f(i,\lceil\frac{j}{2}\rceil)+B_i\) 会不会影响答案呢?

不会,因为此时总会多加一个 \(A_i\),一定不会比从 \(f(i-1,j+1)\) 来优。

怎么想到的啊 QAQQAQQAQQAQQAQ

posted @ 2024-09-09 07:36  Laijinyi  阅读(1)  评论(0编辑  收藏  举报