1. 程式人生 > 實用技巧 >1743最優合併問題(貪心)

1743最優合併問題(貪心)

Description

給定k 個排好序的序列s1, s2,……, sk, 用2 路合併演算法將這k 個序列合併成一個序列。假設所採用的2 路合併演算法合併2 個長度分別為m和n的序列需要m + n -1次比較。試設計一個演算法確定合併這個序列的最優合併順序,使所需的總比較次數最少。
為了進行比較,還需要確定合併這個序列的最差合併順序,使所需的總比較次數最多。
對於給定的k個待合併序列,計算最多比較次數和最少比較次數合併方案。

Input

輸入資料的第一行有1 個正整數k(k≤1000),表示有k個待合併序列。接下來的1 行中,有k個正整數,表示k個待合併序列的長度。

Output

輸出兩個整數,中間用空格隔開,表示計算出的最多比較次數和最少比較次數。

Sample

Input

4
5 12 11 2

Output

78 52
 1 #include <iostream>
 2 #include <algorithm>
 3 #include <string.h>
 4 #include <vector>
 5 #include <queue>
 6 
 7 #define inf 0x3f3f3f3f
 8 
 9 using namespace std;
10 
11 priority_queue<int, vector<int>, greater<int> > q1;
12 priority_queue<int, vector<int>, less<int> > q2; 13 14 int main() 15 { 16 int n, x, i, sum, sum1, sum2; 17 cin >> n; 18 for(i=0; i<n; i++) 19 { 20 cin >> x; 21 q1.push(x); 22 q2.push(x); 23 } 24 sum1 = 0; 25 while(q1.size()!=1
) 26 { 27 sum = 0; 28 for(i=0;i<2;i++) 29 { 30 sum += q1.top(); 31 q1.pop(); 32 } 33 q1.push(sum); 34 sum--; 35 sum1 += sum; 36 } 37 sum2 = 0; 38 while(q2.size()!=1) 39 { 40 sum = 0; 41 for(i=0;i<2;i++) 42 { 43 sum += q2.top(); 44 q2.pop(); 45 } 46 q2.push(sum); 47 sum--; 48 sum2 += sum; 49 } 50 cout << sum2 << " " << sum1 << endl; 51 return 0; 52 }