【NOI2015】荷马史诗
顯然一個(gè)Huffman樹(shù),然后改成 \(K\) 叉的就好。但是我不會(huì)Huffman樹(shù),于是學(xué)學(xué)拓寬知識(shí)面。
首先這個(gè) \(K\) 叉樹(shù)就是一個(gè)類似字典樹(shù)的東西,但是不對(duì)應(yīng)目標(biāo)串的點(diǎn)都是非葉結(jié)點(diǎn)(不然不滿足前綴關(guān)系的限制)
容易證明,每個(gè)點(diǎn)帶 \(K - 1\) 個(gè)葉子是最優(yōu)的。
考慮計(jì)算總權(quán)值時(shí)的 深度乘以權(quán)值 改為 它到根的鏈上都加上它的權(quán)值,那么 \(\sum dep_i \times val_i = \sum_{u \notin leaves} v_i\)。
于是讓權(quán)值大的盡量貢獻(xiàn)最少,那么就要出現(xiàn)在深度淺的地方。
因此考慮自底向上構(gòu)建。考慮維護(hù)一個(gè)堆,每次取出前 \(K\) 小的,合并成一個(gè)點(diǎn),然后扔進(jìn)堆里。合并的時(shí)候維護(hù)權(quán)值(子節(jié)點(diǎn)的和)。直到合并成單個(gè)點(diǎn)。顯然,權(quán)值越大的貢獻(xiàn)次數(shù)越小。于是這樣貪心是正確的(然而我并不會(huì)嚴(yán)格的證明)。
然后就建出一個(gè) Huffman樹(shù)了。但是對(duì)于第二問(wèn)我們還是要得出深度最小值,于是加入第二關(guān)鍵字深度,合并的時(shí)候注意維護(hù)就行了。
還有因?yàn)槊看螠p少 \(K - 1\) 個(gè),所以可能最后剩下不是 \(1\) 個(gè),所以,補(bǔ)上幾個(gè) \(0\) 使得 \(n \equiv 1\ (\mod K - 1)\),顯然不會(huì)對(duì)答案產(chǎn)生影響。
我掛在了補(bǔ) \(0\) 以及 第二關(guān)鍵字上,WA了兩發(fā)。
#include <bits/stdc++.h>typedef long long LL; typedef std::pair<LL, int> P; std::priority_queue<P, std::vector<P>, std::greater<P> > q; int n, K; LL t; int main() {std::ios_base::sync_with_stdio(false), std::cin.tie(0);std::cin >> n >> K;for (int i = 1; i <= n; ++i) std::cin >> t, q.emplace(t, 0);while (n % (K - 1) != 1 % (K - 1)) ++n, q.emplace(0, 0);LL ans = 0;while (q.size() != 1) {LL tv = 0; int dx = 0;for (int i = 1; i <= K; ++i)tv += q.top().first, dx = std::max(dx, q.top().second), q.pop();q.emplace(tv, dx + 1); ans += tv;}std::cout << ans << std::endl << q.top().second << std::endl;return 0; }轉(zhuǎn)載于:https://www.cnblogs.com/daklqw/p/11587281.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的【NOI2015】荷马史诗的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 黑马lavarel教程---9、缓存操作
- 下一篇: 【集训队作业2018】复读机