Luogu [P1334] 瑞瑞的木板(手写堆)

其实这个题完全不需要用手写堆,只需要一遍遍sort就行了……

但是!

为了练习手写堆,还是用手写堆做了。

在做本题之前,如果你没有什么思路的话,建议先做Luogu的合并果子

好,假设你已经做过了合并果子了。那么正式开始本题:

相信许多人都已经知道了这道题就是合并果子,但是还不知道它是怎样转化成合并果子的,其实很简单:比如说9 7 6 5 3,有些同学可能会想:每次我砍最大的,然后剩下的不就少了。其实不然,因为不一定一次只能砍一个,可以砍两个或两个以上。不多说,我把上面例子的最优策略讲出来大概就知道了。step1:把9+7+6+5+3切成7+6和5+3+9两部分;step2:把7+6切成7和6;step3:把5+3+9切成5+3和9两部分:step4:把5+3切成5和3。这时我们再回过头来看,是不是就是合并果子的步骤?

AC代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
long long x,n,tot,dl[100001],sum;//小根堆 
char c;
void delete_2(long long num)
{
    if(((num<<1)+1)<=tot)
    {
        if(dl[num<<1]<dl[(num<<1)+1])
        {
            if(dl[num]<dl[num<<1])
                return ;
            else
            {
                swap(dl[num],dl[num<<1]);
                delete_2(num<<1);
            }
        }
        else
        {
            if(dl[num]<dl[(num<<1)+1])
                return ;
            else
            {
                swap(dl[num],dl[(num<<1)+1]);
                delete_2((num<<1)+1);
            }
        }
    }
    else
    {
        if((num<<1)<=tot)
        {
            if(dl[num]<dl[num<<1])
                return ;
            else
            {
                swap(dl[num],dl[num<<1]);
                delete_2(num<<1);
            }
        }
        else
            return ;
    }
    return ;
}

void delete_1()//删除操作
{
    dl[1]=dl[tot--];
    delete_2(1);
}

void qcr(long long num)  //名字随便取的
{
    if(num==1)
        return ;
    if(dl[num]<dl[num>>1])
    {
        swap(dl[num],dl[num>>1]);
        num>>=1;    
        qcr(num);
    }
    return ;
}

void putin(long long x)  //添加操作
{
    dl[++tot]=x;
    qcr(tot);
}

void putout()     //读取操作
{
    printf("%d",dl[1]);
    return ;
} 

int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>x;
        putin(x);
    }
    for(int i=1;i<n;i++)
    {
        int q,p;
        q=dl[1];
        delete_1();
        p=dl[1];
        delete_1();
        sum+=p+q;
        putin(p+q);
    }
    cout<<sum;
    return 0;
}

 

原文地址:https://www.cnblogs.com/qiuchengrui/p/8995194.html