多元Huffman编码问题

多元Huffman编码问题

Time Limit: 1000 ms Memory Limit: 65536 KiB

Problem Description

在一个操场的四周摆放着n堆石子。现要将石子有次序地合并成一堆。规定每次至少选2 堆最多选k堆石子合并成新的一堆,合并的费用为新的一堆的石子数。试设计一个算法,计算出将n堆石子合并成一堆的最大总费用和最小总费用。
对于给定n堆石子,计算合并成一堆的最大总费用和最小总费用。

Input

输入数据的第1 行有2 个正整数n和k(n≤100000,k≤10000),表示有n堆石子,每次至少选2 堆最多选k堆石子合并。第2 行有n个数(每个数均不超过 100),分别表示每堆石子的个数。

Output

将计算出的最大总费用和最小总费用输出,两个整数之间用空格分开。

Sample Input

7 3
45 13 12 16 9 5 22

Sample Output

593 199

Hint

请注意数据范围是否可能爆 int。

Source

 优化之后的:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n;
 4 long long maxNum,minNum;
 5 template<class T>
 6 long long result(T q,int k,int flag){
 7     if(flag==1&&n>k){// 求最小的 更新
 8         int tmp=n;
 9         while(tmp>k) tmp=tmp-(k-1);
10         for(int i=0;i<k-tmp;i++) q.push(0);
11     }
12     long long rst=0;
13     while((int)q.size()>k){
14         long long sum=0;//sum   k个 先后堆顶相加的值,合并之后,需要把sum 继续放进 优先队列里面 ,继续参与下面的合并
15         for(int i=0;i<k;i++){
16             sum+=q.top();//sum 加上堆顶的值
17             q.pop();//同时需要把这个 堆顶的值删除
18         }
19         rst+=sum;//合并 费用 更新
20         q.push(sum);//将合并的值  继续放进 优先队列 参与 下面的合并
21     }
22     while(!q.empty()){//合并 之后  优先队列(即堆) 里面还剩下 k  个 数据   这两堆合并 的费用 就是它们的两个的和
23        rst+=q.top();//费用值  + 剩余的 两对 合并费用 结束
24        q.pop();
25     }
26     return rst;//返回
27 }
28 int main()
29 {
30     int k,data;
31     priority_queue<long long> q;//默认 从大 到小
32     priority_queue<long long,vector<long long>,greater<long long> > p;  //从小到大的顺序排列队列中的数据    cin>>n>>k;//输入n堆石子,每次至少选2 堆最多选k堆石子合并
33     cin>>n>>k;
34     for(int i=0;i<n;i++){
35         cin>>data;
36         q.push(data);
37         p.push(data);
38     }
39     maxNum=result(q,2,0);//k =2  求最大 k=2
40     minNum=result(p,k,1);// k堆
41     cout<<maxNum<<" "<<minNum<<endl;
42     return 0;
43 }
原文地址:https://www.cnblogs.com/NirobertEinteson/p/11922644.html