HDU5884 二分+哈弗曼树

25 篇文章 0 订阅
7 篇文章 0 订阅

传送门

huffman模板,如果每次取k个能取完,num=k,取不完先将n%(k-1)取完,再每次取k

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef long long ll;
int arr[N], n, limit;
/****************************/
int a[N], b[N<<3];
bool Huffman(int k){
    int ai, bi, lenb, lena, num;
    bool first=true;
    ai=bi=lenb=lena=0;

    for(int i=1; i<=n; i++)
        a[lena++]=arr[i];

    ll s=0;
    while(n-ai+lenb-bi>1){
        if(first){
            if((n-k)%(k-1)==0)
                num=k;
            else
                num=n%(k-1);
            first=false;
        }
        else
            num=k;
        ll sum=0;
        while(num--){
            if(ai==lena)
                sum+=b[bi++];
            else if(bi==lenb)
                sum+=a[ai++];
            else if(a[ai]>b[bi])
                sum+=b[bi++];
            else
                sum+=a[ai++];
        }
        b[lenb++]=sum;
        s+=sum;
    }
    if(s>limit)
        return false;
    else
        return true;
}
/*****************************/
int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        scanf("%d%d", &n, &limit);
        for(int i=1; i<=n; i++)
            scanf("%d", arr+i);

        sort(arr+1, arr+1+n);
        int l=2, r=n, ans;
        while(l<=r){
            int mid=(l+r)>>1;
            if(Huffman(mid)){
                ans=mid; r=mid-1;
            }
            else
                l=mid+1;
        }
        printf("%d\n", ans);
    }

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值