Educational Codeforces Round 31-k叉哈夫曼&优先队列&好题-D. Boxes And Balls

33 篇文章 0 订阅
12 篇文章 0 订阅

http://codeforces.com/contest/884/problem/D
给定一个n。
然后是n个不同颜色的球的数目。
开始这些球都在第一个盒子里。
你有下面的操作方法
① 把某一个不空盒子种的球拿出来。
② 把这些球按颜色装到3个或者2个盒子里,不同颜色可以装在一起。
而每次这种操作的花费为 你第一个操作拿出的球的数目。
问你如何操作,能够使花费最小。


一点都不显然,这时一个k叉哈夫曼,我也是画图才发现。随着哈夫曼树叉树的增加,他的最小带权路径长度也再慢慢变小。但是编码所需字符集也在慢慢增多。所以这道题就是构造三叉哈夫曼就阔以了。
k叉哈夫曼的构造方法(by 大佬):
构造的思路。
每次选择最小的k个来放置。
但是容易发现最后可能不够k个,那怎么办捏
假设有n个节点,k叉,最后剩一个。
容易得到,n-1是k-1的倍数。
如果(n-1)%(k-1)!=0,
那么就要再放入(k-1-(n-1)%(k-1))个虚拟点,
并且它们的权值为0,它们也参与求最小k个点。
其实就是加点了。

  #include <bits/stdc++.h>
using namespace std;
/* 
*/
typedef long long ll;
struct cmp{
  bool operator()(ll x,ll y){
      return x>y;
  }
};
priority_queue<ll,vector<ll>,cmp>q;
int t;
ll a;
int main() {
    while(~scanf("%d",&t)){
          ll sum=0;
          while(!q.empty()) q.pop();
          for(int i=0;i<t;i++){
             scanf("%lld",&a);
             q.push(a);
          }
          if((t-1)%2!=0){
            int x=(2-(t-1)%2);
            for(int i=0;i<x;i++)
                q.push(0);
          }
          while(q.size()>=3){
                ll a=0;
                ll u1=q.top();q.pop();
                a+=u1;
                ll u2=q.top();q.pop();
                a+=u2;
                ll u3=q.top();q.pop();
                a+=u3;
                sum+=a;
                q.push(a);
          }
          printf("%lld\n",sum);
    }
    return 0;
}

有巨佬的写法貌似不是这样,但是思路是一样的,大佬没有加点,但是在剩余节点为偶数的情况下选择只取2个最小的。(其实是一样的,经过我手算发现只有偶数的第一次可以出现这种情况,而也只有这种情况是加0 的,并且只加一个0,巧了,另一个大佬的代码就是酱紫,根据t的奇偶性,如果是偶数就加一个qwq)
这里写图片描述
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值