zoukankan      html  css  js  c++  java
  • POJ 3253 Fence Repair(哈夫曼编码)

    题目链接:http://poj.org/problem?id=3253

    题目大意:

    有一个农夫要把一个木板钜成几块给定长度的小木板,每次锯都要收取一定费用,这个费用就是当前锯的这个木版的长度

    给定各个要求的小木板的长度,及小木板的个数n,求最小费用

    3

    5 8 5为例:

    先从无限长的木板上锯下长度为 21 的木板,花费 21

    再从长度为21的木板上锯下长度为5的木板,花费5

    再从长度为16的木板上锯下长度为8的木板,花费8

    总花费 = 21+5+8 =34

    解题思路:哈夫曼编码模板

    代码:

    使用数组的普通方法:

     1 #include<iostream>
     2 #include<queue>
     3 #include<vector>
     4 #include<algorithm>
     5 using namespace std;
     6 typedef long long ll;
     7 //输入
     8 int n,a[20005];
     9 
    10 //使用数组维护最大最小值(每次维护复杂度O(n)) 
    11 void solve1(){
    12     ll ans=0;
    13     
    14     while(n>1){
    15         int mi1=0,mi2=1;//mi1最小值的下标,mi2次小值的下标 
    16         if(a[mi1]>a[mi2]) swap(mi1,mi2);
    17         for(int i=2;i<n;i++){
    18             if(a[mi1]>a[i]){
    19                 mi2=mi1;
    20                 mi1=i;    
    21             }
    22             else if(a[mi2]>a[i]){
    23                 mi2=i;
    24             }
    25         }
    26         int t=a[mi1]+a[mi2];
    27         ans+=t;
    28         if(mi1==n-1) swap(mi1,mi2);
    29         a[mi1]=t;
    30         a[mi2]=a[n-1];
    31         n--;
    32     }
    33     cout<<ans<<endl;
    34 }
    35 int main(){ 
    36     cin>>n;
    37     for(int i=0;i<n;i++){
    38         cin>>a[i];
    39     }
    40     solve1(); 
    41     return 0;
    42 } 

    使用STL优先队列:

     1 #include<iostream>
     2 #include<queue>
     3 #include<vector>
     4 #include<algorithm>
     5 using namespace std;
     6 typedef long long ll;
     7 //输入
     8 int n,a[20005];
     9 //优先队列维护最小与次小值(初始化复杂度O(n),每次维护复杂度O(log2n))
    10 void solve2(){
    11     priority_queue<ll,vector<ll>,greater<ll> >q;
    12     ll ans=0;
    13     for(int i=0;i<n;i++){
    14         q.push(a[i]);
    15     }
    16     while(q.size()>1){
    17         ll mi1=q.top();//最小
    18         q.pop();
    19         ll mi2=q.top();//次小
    20         q.pop();
    21         q.push(mi1+mi2);//合并 
    22         ans+=mi1+mi2; 
    23     }
    24     cout<<ans<<endl;
    25 } 
    26 int main(){ 
    27     cin>>n;
    28     for(int i=0;i<n;i++){
    29         cin>>a[i];
    30     }
    31     solve2(); 
    32     return 0;
    33 } 
  • 相关阅读:
    2018年5月29号(堆排序最小顶)
    2018年5月31号(树状数组)
    2018年5月27号(spfa判断负环)
    2018年6月1号(线段树(1))
    2018年5月28号(差分约束)
    Inno Setup入门(十二)——Pascal脚本(1)
    Inno Setup入门(十六)——Inno Setup类参考(2)
    Inno Setup入门(二十一)——Inno Setup类参考(7)
    Inno Setup入门(十)——操作注册表
    Inno Setup入门(十八)——Inno Setup类参考(4)
  • 原文地址:https://www.cnblogs.com/fu3638/p/6958120.html
Copyright © 2011-2022 走看看