1. 程式人生 > >【BZOJ4198】【UOJ130】【NOI2015】荷馬史詩

【BZOJ4198】【UOJ130】【NOI2015】荷馬史詩

【題目連結】

【思路要點】

  • 如果將一個合法的分配方案放到字典樹上,那麼每一個關鍵節點均為葉子結點。
  • 考慮如何使答案最小化,資料範圍較大,考慮貪心。
  • 我們注意到一系列具有相同父親的葉子結點可以被看作一個大小為它們大小總和的葉子結點。
  • 我們稱之為一次合併,我們不斷地執行合併,最後就會得到字典樹上的根節點。
  • 由於我們希望使最小化答案,而一個葉子結點被合併的次數越多,其大小在答案中被計算的次數也越多,所以在執行合併時,我們會盡量選取大小較小的葉子進行合併。
  • 具體實現時可以用一個堆來實現這個過程,注意第一次合併的葉子的數量可能不是\(K\),而是\((N-1)\%(K-1)+1\)。
  • 第二問只需要在滿足以上限制的情況下選取深度儘量小的葉子即可。
  • 時間複雜度\(O(NLogN)\)。

【程式碼】

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); } 
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
template <typename T> void write(T x) {
	if (x < 0) x = -x, putchar('-');
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) {
	write(x);
	puts("");
}
struct info {long long size; int depth; };
bool operator < (info a, info b) {
	if (a.size == b.size) return a.depth > b.depth;
	else return a.size > b.size;
}
priority_queue <info> Heap;
long long ans; int n, m;
void merge(int cnt) {
	if (cnt == 1) return;
	long long now = 0; int depth = 0;
	for (int i = 1; i <= cnt; i++) {
		info tmp = Heap.top();
		Heap.pop();
		now += tmp.size;
		chkmax(depth, tmp.depth);
	}
	ans += now;
	Heap.push((info) {now, depth + 1});
}
int main() {
	read(n), read(m);
	for (int i = 1; i <= n; i++) {
		long long x; read(x);
		Heap.push((info) {x, 0});
	}
	merge((n - 1) % (m - 1) + 1);
	while (Heap.size() != 1) merge(m);
	writeln(ans);
	writeln(Heap.top().depth);
	return 0;
}

相關推薦

LOJ#2132. 「NOI2015史詩

amp bitset 感覺 nbsp 個數 none sin splay cstring $n \leq 100000$個數字,放進$k$叉樹裏,一個點只能放一個數,使所有數字乘以各自深度這個值之和最小的同時,最大深度的數字最小。 哈夫曼。這是我剛學OI那段時間看到的,感覺

BZOJ4198UOJ130NOI2015史詩

【題目連結】BZOJUOJ【思路要點】如果將一個合法的分配方案放到字典樹上,那麼每一個關鍵節點均為葉子結點。考慮如何使答案最小化,資料範圍較大,考慮貪心。我們注意到一系列具有相同父親的葉子結點可以被看作

huffmanbzoj4198:UOJ#130 [Noi2015]史詩

Description Time Limit: 10 Sec Memory Limit: 512 MB 追逐影子的人,自己就是影子。 ——荷馬 Allison 最近迷上了文學。她喜歡在一個慵懶的午後,細細地品上一杯卡布奇諾,靜靜地閱讀她愛

BZOJ4198UOJ130 史詩 K叉哈夫曼樹

題解: 用一個堆來維護一個K叉哈夫曼樹,如果無法合併(即n-1不為k-1的倍數時),就補充n-k個虛擬節點,節點的權值為0(不會影響結果),再合併即可。 程式碼: #include <

UOJ#130 NOI2015史詩 K叉哈夫曼樹

i++ getchar ext getch pre user sum spec getc 【NOI2015】荷馬史詩 鏈接:http://uoj.ac/problem/130 因為不能有前綴關系,所以單詞均為葉子節點,就是K叉哈夫曼樹。第一問直接求解,第二問即第二關鍵

BZOJ 4198[Noi2015]史詩 哈夫曼編碼

clu tor space zoj col 具體實現 %d sca bool 合並果子加強版....... 哈夫曼樹是一種特別的貪心算法,它的作用是使若幹個點合並成一棵樹,每次合並新建一個節點連接兩個合並根並形成一個新的根,使葉子節點的權值乘上其到根的路徑長的和最短(等價

BZOJ4198史詩,貪心之k叉哈夫曼樹

傳送門 思路: 很早以前聽說過這個題 據說是一個很強的貪心(?) 然後一上來就往貪心上去想……(其實一開始知道演算法不是很好,因為你不會走彎路了) 發現這玩意好像是個合併果子的模型…… 也不

洛谷P2168史詩

輸入 bool spa priority 新的 輸出格式 inline 格式 += 題目描述 追逐影子的人,自己就是影子 ——荷馬 Allison 最近迷上了文學。她喜歡在一個慵懶的午後,細細地品上一杯卡布奇諾,靜靜地閱讀她愛不釋手的《荷馬史詩》。但是由《奧德賽》和《伊利亞

NOI 2015 史詩

print tor 優先 queue urn amp IT () 就是 【題目鏈接】 https://www.lydsy.com/JudgeOnline/problem.php?id=4198 【算法】 不難發現,題目中所說的

BZOJ4198: [Noi2015]史詩(哈夫曼樹)

成了 inpu const 包含 printf 來替 iso stat .com Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1824 Solved: 983[Submit][Status][Discuss] Desc

bzoj4198 [Noi2015] [史詩] Huffman 編碼

1.維護k叉樹,注意補零 2.用堆來維護最小的頻率和長度,每次向上合併,在合併時統計答案 3.如果 n % (k-1)=1那麼就不用補零(因為每次合併就相當於增加k-1個節點,所有如果能合併成一個節

貪心+哈夫曼樹--bzoj4198[NOI2015]史詩

傳送門 看到這個題一臉懵逼啊?難道是字串?? 結果一看題解,是什麼哈夫曼樹(不會啊) 這裡留個坑···還沒有十分了解哈夫曼樹是啥 但是看樣子好像就是一棵二叉樹,每次將權值小的合併成新的點 新點權值是原來的和 這個背景好像很裸??? Huffman樹

BZOJ 4198[Noi2015]史詩

表示 ans per 方案 滿足 amp opera priority int 4198: [Noi2015]荷馬史詩 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1408 Solved: 746[Submit][St

NOI2015 史詩 [哈夫曼樹]

per inpu h+ 正是 存在 space pre 節點 noi2015 Description 一部《荷馬史詩》中有n種不同的單詞,從1到n進行編號。其中第i種單 詞出現的總次數為wi。Allison 想要用k進制串si來替換第i種單詞,使得其滿足如下要求: 對於任意

4198: [Noi2015]史詩 (哈夫曼樹基礎)

如何選擇 是否 scrip print for scanf 表示 stat tor 一、題目概述 4198: [Noi2015]荷馬史詩 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1545 Solved: 818[Su

[NOI2015]史詩

AC #define int() pop ace efi print tro air 題目:洛谷P2168、codevs5501。 題目大意:有n種單詞,每種單詞有一個出現次數。現在要用k進制字符串代表這些單詞,使得任意一個字符串不是另一個的前綴。問:最短的總長度是多少?

4198: [Noi2015]史詩

題目連結 題目大意:一篇文章有n個單詞,其中第i個單詞的出現次數為w[i]。你要用k進位制串s[i]替換第i種單詞。要求:對於任意i!=j,都有s[i]不是s[j]的字首。 要使替換後的文章總長度最小。 求這個最小總長度。 在這個前提下,要使s[i]的最

史詩NOI2015)提高組

1. Problem Description 追逐影子的人,自己就是影子 ——荷馬 Allison 最近迷上了文學。她喜歡在一個慵懶的午後,細細地品上一杯卡布奇諾,靜靜地閱讀她愛不釋手的《荷馬史詩》。但是由《奧德賽》和《伊利亞特》 組成的鴻篇鉅製《荷馬史詩》

[BZOJ]4198: [Noi2015]史詩

getchar 數據 stat 網上 clas tchar esp 存在 得到  題解: 提高組系列難度題.....竟然各種假貪心 瞄了網上結論 竟然 n%(k-1)不足1要補齊....orz這個真沒想到 漲知識漲知識.... 補齊以後直接類似合並果子 堆貪心就行了

[K叉哈夫曼樹]BZOJ 4198—— [Noi2015]史詩

題目概述 並不是很想寫概述啊。 這不是許可權題,來個連結大家自己看下吧:題目傳送門 解題思路 相信大家看來這道題之後都不難聯想到哈夫曼編碼的原理。 Ps:不知道哈夫曼編碼,問度娘去吧。 這麼看來這道題轉變為另外一個問題: 求一棵K叉哈夫曼樹的最