zoukankan      html  css  js  c++  java
  • 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;
    }

     

  • 相关阅读:
    List 与 Array 的相互转化及 List、Array、Set转为 String
    Java 序列化介绍及 Redis 序列化方式
    SpringBoot 整合 redis 实现 token 验证
    SpringBoot 整合 Redis 使用
    Map 某 value 为 对象数组,转为 ArrayList 对象集合
    JWT 基本使用
    Spring session + redis 实现 session共享入门
    HttpServletRequest + Filter 添加 header
    Git ahead(超前) 又behind(落后)
    web应用中路径跳转问题-相对路径、绝对路径
  • 原文地址:https://www.cnblogs.com/qiuchengrui/p/8995194.html
Copyright © 2011-2022 走看看