实验任务
小明的家具包含 \(n\) 个箱子,每个箱子有各自的重量。由于绳子长度有限,他每次只能把最多 \(k\)个箱子绑在一起形成一个新箱子,新箱子的重量为被绑的箱子重量之和。这样绑一次,小明耗费的体力值是被绑的箱子重量之和(即新箱子的重量)。并且新箱子还可以作为一个箱子参与后续的操作。
小明想经过若干次操作,最终把所有的箱子打包成一个箱子。那么他耗费的总体力值最小是多少?
例如,假设一开始有 3 个箱子,重量为 1、2、4,\(k=2\)。那么可以先把 24 绑在一起形成一个重量为 6 的箱子,再把它和重量为 1 的箱子绑在一起,耗费的总体力值是\((2+4)+(6+1)=13\)。也可以先绑 1 和 4 得到 5,再绑 2 和 5,耗费的总体力值是\((1+4)+(2+5)=12\),后一种方案耗费的体力值更小,但这也不是最优的绑法。
数据输入
输入第一行为两个正整数 \(n\), \(k\),含义如上。接下去 \(n\) 个正整数,表示最开始 \(n\) 个箱子的重量,以空格隔开。
数据输出
输出一行,表示最小总花费。
输入示例 | 输出示例 |
---|---|
3 2 1 2 4 |
10 |
5 3 1 1 1 1 1 |
8 |
数据范围
最开始 \(n\) 个箱子的重量均在\([1, 1000]\)内;\(50\%\)的得分点,\(n\leq 3\),\(k=2\);其余 \(30\%\)的得分点,\(n\leq 100000\),\(k=2\);其余 \(20\%\)的得分点,\(n, k\leq 100000\),\(k\geq 2\)。
源代码
1 |
|
设计思路与复杂度分析
\(k\)叉哈夫曼树需要满足的性质:保证每一个非页节点都有\(k\) 个子节点。
如何保证节点页节点数满足性质?考虑特殊情况:第一次\(k\)个叶子节点计算,其余的都是\((k-1)\)个叶子节点与刚才生成的分支节点计算。
反过来考虑:假设第一次也是\((k-1)\)个节点参与计算,这样相当于总数少了1,变成了\(n-1\)个节点每次\((k-1)\)的独立运算!所以当\((n-1)\%(k-1)=0\)时,刚好构造一棵\(k\)叉树。
对每一个箱子需要插入优先队列然后从优先队列取出(只是计算复杂度无需考虑生成的中间节点),所以复杂度为:\(O(nlogn)\)。