合并果子(堆写法)

题目大意:

一个小朋友从树上打下了几堆果子。要将所有果子合并成一堆。给出没堆果子的重量求最小力气

本题的思路是要将重量最小的先合并,也就是传说中的哈夫曼树!但本题的数据比较大。今天我们来看堆得写法:

# include<stdio.h>
# include<stdlib.h>
long long a[1000010];
int main(){
    long long sum=0,ans=0,n,i,h,r,j;//本题要用long long不然会答案错误
    scanf("%I64d",&n);
    for(i=1;i<=n;i++){
        scanf("%I64d",&a[i]);//将重量存入堆
         r=i;//上浮
        while(r>1&&a[r]<a[r/2]){ 
            h=a[r];
            a[r]=a[r/2];
            a[r/2]=h;
            r/=2;
        }
    }
    int len=n;
    for(i=1;i<n;i++){
        sum=a[1];//将当前最小的放到本次合并中
        a[1]=a[len];
        len--;
        r=1;//下沉
        while((r*2<=len&&a[r]>a[r*2])||(r*2+1<=len&&a[r]>a[r*2+1])){
            j=r*2;
            if(j+1<=len&&a[j]>a[j+1])j++;
            h=a[r];
            a[r]=a[j];
            a[j]=h;
            r=j;
        }
        sum+=a[1];//将第二小的加入本次合并中
        a[1]=a[len];
        len--;
        r=1;//下沉
        while((r*2<=len&&a[r]>a[r*2])||(r*2+1<=len&&a[r]>a[r*2+1])){
            j=r*2;
            if(j+1<=len&&a[j]>a[j+1])j++;
            h=a[r];
            a[r]=a[j];
            a[j]=h;
            r=j;
        }
        ans+=sum;//合并
        a[++len]=sum;
        r=len;//上浮
        while(r>1&&a[r]<a[r/2]){
            h=a[r];
            a[r]=a[r/2];
            a[r/2]=h;
            r/=2;
        }
    }
    printf("%I64d\n",ans);
}
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35124363/article/details/51536309
文章标签: c
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

合并果子(堆写法)

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭