有n堆石子形成一行(a1,a2,…,an,ai為第i堆石子個數),現要將石子合併成一堆,規定每次可選擇至少2堆最多k堆移出然後合併,每次合併的分值為新堆的石子數。若干次合併後,石子最後肯定被合併為一堆,得分為每次合併的分值之和。現在求解將這n堆石子合併成一堆的最低得分和最高得分。
(1)保證每次選兩堆最多的,合併直至只剩一堆為止,能獲得最大得分;這個和huffman樹構造是相同的,不再詳述!
(2)保證每次選k堆最少的,合併直至只剩一堆為止,能獲得最小得分。這個是多元huffman樹的構造。要注意的是:在合併之前,若n%(k-1)!=1,說明合併到最後一輪時,
剩下不是k堆(而是比k堆少),這樣算的並不是最小得分,而必須在合併之前新增若干個為0的虛擬堆,目的為湊成的堆數保證每次都能有k堆合併(包括最後一次)最後合併為1堆。因此,在合併前作如下處理:
//假設石頭每堆個數放於stone[1]~stone[n],且stone[n]之後最多k-1個陣列單元為可寫;
while (n % (k - 1) != 1)
看完上面的分析之後是不是很清晰了?感覺這道題更偏重於考察資料結構。剛開始想要自己寫一下堆的實現的,發現忘記了好多,查了一下c++裡面有提供。看來資料結構是該重新拾起來了。
#include
#include
#include
using
namespace std;
intsolvemax
(priority_queue<
int> maxheap)
return maxcount;
}int
solvemin
(priority_queue<
int, vector<
int>
, greater<
int>
> minheap,
int n ,
int k)
int mincount =0;
while
(minheap.
size()
!=1) minheap.
push
(min)
; mincount +
= min;
}return mincount;
}int
main()
cout <<
solvemin
(minheap, n, k)
<<
" "<<
solvemax
(maxheap)
;return0;
}
11079 可以移動的石子合併
11079 可以移動的石子合併 時間限制 1000ms 記憶體限制 1000k 題型 程式設計題語言 無限制 description 有n堆石子形成一行 a1,a2,an,ai為第i堆石子個數 現要將石子合併成一堆,規定每次可選擇至少2堆最多k堆移出然後合併,每次合併的分值為新堆的石子數。若干次合併...
不能移動的石子合併
時間限制 1000ms 記憶體限制 1000k 提交次數 0 通過次數 0 題型 程式設計題 語言 g gcc vc 做如下兩個模型的石子合併,如下模型石子都不能移動出列,且合併都僅發生在相鄰兩堆石子中 1 第乙個模型 一行排列且相鄰合併 有n堆石子a1,a2,an形成一行,每堆石頭個數記為ai 1...
石子合併問題
在乙個圓形操場的四周擺放著n堆石子。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的得分。試設計乙個演算法,計算出將n堆石子合併成一堆的最小得分和最大得分。分析 假設有n堆石子需要合併,可以設計乙個2 n 1個元素的陣列來儲存每堆石子的個數。...