题意:给出n根木板,需要把它们连接起来,每一次连接的花费是他们的长度之和,问最少需要多少钱。
和上一题果子合并一样,只不过这一题用long long
学习的手写二叉堆的代码,再好好理解= =
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #include<stack> 6 #include<vector> 7 #include<map> 8 #include<queue> 9 #include<algorithm> 10 #define mod=1e9+7; 11 using namespace std; 12 13 typedef long long LL; 14 const int maxn=50005; 15 int l[maxn]; 16 int n,h,minn; 17 LL ans; 18 19 void heap_sort(int x){//这是一个小根堆 20 int lg,lr; //lg代表头的左边的节点, lr代表头的右边的节点 21 while((x<<1)<=h){ 22 lg=x<<1; 23 lr=(x<<1)+1; 24 25 if(lr<=h&&l[lg]>l[lr]) 26 lg=lr; 27 if(l[x]>l[lg]){ 28 swap(l[x],l[lg]); 29 x=lg; 30 } 31 else 32 break; 33 } 34 } 35 36 int main(){ 37 int i; 38 while(scanf("%d",&n)!=EOF){ 39 for(i=1;i<=n;i++) 40 scanf("%d",&l[i]); 41 42 h=n; 43 for(i=n/2;i>0;i--) 44 heap_sort(i); 45 46 ans=0; 47 48 while(h>1){ 49 minn=l[1];//取出当前的根,也就是当前最小的一个数 50 l[1]=l[h];h--;//把最后一个数放到第一个位置 51 heap_sort(1);//下降操作 52 53 minn+=l[1];//下降完之后,又取出当前的根,也即为最小的一个数 54 l[1]=minn;//将当前新和成的这一堆又加进去 55 heap_sort(1);//下降操作 56 57 ans+=minn; 58 } 59 60 printf("%I64d\n",ans); 61 } 62 return 0; 63 }
把上一题代码稍微一改,用优先队列
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #include<stack> 6 #include<vector> 7 #include<map> 8 #include<queue> 9 #include<algorithm> 10 #define mod=1e9+7; 11 using namespace std; 12 13 typedef long long LL; 14 15 int main(){ 16 17 int n,a; 18 while(scanf("%d",&n)!=EOF){ 19 priority_queue<int,vector<int>,greater<int> > pq; 20 LL ans=0; 21 22 for(int i=1;i<=n;i++){ 23 scanf("%d",&a); 24 pq.push(a); 25 } 26 27 while(pq.size()>1){ 28 int x=pq.top();pq.pop(); 29 int y=pq.top();pq.pop(); 30 ans+=x+y; 31 pq.push(x+y); 32 } 33 printf("%I64d\n",ans); 34 } 35 return 0; 36 }
时间: 2024-11-05 16:29:14