hoj2677 Instruction Set // poj3253Fence Repair 哈夫曼树

/*

哈弗曼编码,比如权值为 a:1 b:1 c:2 d:3 e:5 f:6 的树

   1.开始时由最小的两个数 a:1 b:1组成一棵树

   2.接着由新的最小的两个数 2 c:2 d:3 e:5 f:6 中的 2 c:2组成新的树

   3.接着由最小的两个数 4 d:3 组成新的树

   4.接着由最小的两个数 e:5 f:6 组成一棵树

   5.接着由最小的两个数 7 11 组成一棵树(最终形成)

   6.算最小的编码总长:= 18 + 7 + 11 + 4 + 2 = 42

 

   2        4           7        11          18

   / \       / \       / \       /  \         /  \

  a   b    2   c     4   d   e    f       7   11

           / \         / \                   / \  / \

          a   b      2  c                 4  d  e  f

                    / \                    / \

                   a   b                 2   c

                                         / \

                                        a   b

 

可以用优先队列做,优先队列每次插入都是插入到排完序后的队列数组中(可能不是很准确),

当还没开始建树时,把出现的次数进队,当开始建树时,每次调用头两个数据a和b,然后把两个数据

相加后,再次进队,同时优先队列会进行排序,并且每次ans += a+b,最终答案即为ans

*/

 

#include <iostream>

#include <string>

#include <queue>

#include <vector>

using namespace std;

string s;

int main()

{

   freopen("sum.in","r",stdin);

   freopen("sum.out","w",stdout);

   int n,command;

   while(cin>>n)

   {

      priority_queue<int ,vector<int>,greater<int> > q; //注意,此处> >是有空格的

      int worst = 0,ans = 0;

      for(int i=0;i<n;i++)

      {

         cin>>s>>command;

         worst+=command*s.size();    //最坏情况需要的空间

         q.push(command);            //把数据进队

      }

      int a,b;

      if(q.size()==1)                //当之有一个串时

         ans = q.top();

      while(true)

      {

         a = q.top();

         q.pop();

         if(q.empty())   //只剩下一个根节点,就已经构成了一棵树

            break;

         b = q.top();

         q.pop();

         ans+=a+b;   //答案

         q.push(a+b); //把新生成的树的权值进队

      }

      cout<<worst<<" "<<ans<<endl;

   }

   return 0;

}

 

poj3253Fence Repair

#include <iostream>

#include <queue>

#include <vector>

using namespace std;

int main()

{

   freopen("sum.in","r",stdin);

   freopen("sum.out","w",stdout);

   int n,t,a,b;

   while(cin>>n)

   {

      long long ans = 0;    //要为long long型才不会WA

      priority_queue<int ,vector<int>,greater<int> > q;

      for(int i=0;i<n;i++)

      {

         cin>>t;

         q.push(t);

      }

      if(q.size()==1)

         ans = q.top();

      while(q.size()>1)

      {

         a = q.top();

         q.pop();

         b = q.top();

         q.pop();

         ans += a+b;

         q.push(a+b);

      }

      cout<<ans<<endl;

   }

   return 0;

}

 

 

转载于:https://www.cnblogs.com/yejinru/archive/2012/03/21/2410367.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值