题意:如果要切断一个长度为a的木条需要花费代价a, 问要切出要求的n个木条所需的最小代价。
思路:模拟huffman树,每次选取最小的两个数加入结果,再将这两个数的和加入队列。
注意priority_queue的用法,原型:
1 priority_queue<Type> q; 2 priority_queue<Type,deque<Type>,Comp> q;
其中Type是类型,Comp是比较结构体,比较函数是它的括号重载,比如对int型从小到大排序的Comp结构体如下:
1 struct Comp 2 { 3 bool operator()(const LL& a,const LL&b) const 4 { 5 return a>b; 6 } 7 };
还有要注意的是,不能直接while(!q.empty()),因为每次选取两个数,如果队列只剩下一个数时又要取两个数,此时程序会爆掉,应该用一个while(1)循环,在取出一个数时立刻判断if(q.empty()) break;
不能直接模拟huffman树,直接huffman会超时。
1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<cmath> 6 #include<math.h> 7 #include<algorithm> 8 #include<queue> 9 #include<set> 10 #include<bitset> 11 #include<map> 12 #include<vector> 13 #include<stdlib.h> 14 #include <stack> 15 using namespace std; 16 #define PI acos(-1.0) 17 #define max(a,b) (a) > (b) ? (a) : (b) 18 #define min(a,b) (a) < (b) ? (a) : (b) 19 #define ll long long 20 #define eps 1e-10 21 #define MOD 1000000007 22 #define N 1000000 23 #define inf 1e12 24 ll n; 25 struct Comp{ 26 bool operator()(const ll &a,const ll &b)const{ 27 return a>b; 28 } 29 }; 30 int main() 31 { 32 while(scanf("%I64d",&n)==1){ 33 priority_queue<ll,deque<ll>,Comp> q; 34 for(int i=1;i<=n;i++){ 35 ll x; 36 scanf("%I64d",&x); 37 q.push(x); 38 } 39 ll ans=0; 40 while(1){ 41 ll L=q.top(); q.pop(); 42 if(q.empty()) break; 43 ll R=q.top(); q.pop(); 44 ans+=L; 45 ans+=R; 46 q.push(L+R); 47 } 48 printf("%I64d ",ans); 49 } 50 return 0; 51 }