zoukankan      html  css  js  c++  java
  • Codeforces 631 (Div. 2) E. Drazil Likes Heap 贪心

    https://codeforces.com/contest/1330/problem/E

    有一个高度为h的大顶堆:有2h -1个不同的正整数,下标从1到2h−1,1<i<2h, a[i]<a[⌊i/2⌋].

    现在我们要降低堆的高度,为h,有2g-1个整数,那么我们要删掉2h-2g个数;

    选择索引 i 删除,删除方法如下:

    被删除的节点值为0,代表该节点不存在。

    所以操作后,2g-1个元素的下标在[1,2g-1]范围内;使得剩余元素的总和最小,并且输出调用删除函数时删除的节点下标。

    人话:将高度为h的完全大顶堆删除一部分节点变成高度位g的完全大顶堆,使得剩余部分和最小。

    哈,此题不会,题意也很模糊,官方题解太长了,还是英文,要死了,直接看的博客,发现一个简单明了的;

    参考博客:https://blog.csdn.net/qq_45458915/article/details/105309861?%3E

    思路:删完后仍是完全大顶堆,那么首先保证叶子节点的高度为g,然后尽量删除值最大的节点,删到不能删为止,再删除下一个值较大的节点,也就是贪心的从根节点开始删除,只要满足要删除的节点删除后叶子节点的高度大于等于g就可以了,总之能删就删,不能删就删下一个节点。

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN=1e5+5;
    const int mod=1e9+7;
    typedef long long ll;
    //typedef __int128 LL;
    const int inf=0x3f3f3f3f;
    const long long INF=0x3f3f3f3f3f3f3f3f;
    int a[(1<<(20+1))+10];
    vector<int>ans;
    int getid(int k)
    {
        if(a[k<<1]==0&&a[(k<<1)+1]==0)return k;
        else if(a[k<<1]>a[(k<<1)+1])return getid(k<<1);
        else return getid((k<<1)+1);
    }
    void dfs(int k)
    {
        if(a[k<<1]==0&&a[(k<<1)+1]==0)
        {
            a[k]=0;
            return ;
        }
        else if(a[k<<1]>a[(k<<1)+1])a[k]=a[k<<1],dfs(k<<1);
        else a[k]=a[(k<<1)+1],dfs((k<<1)+1);
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int h,g;
            scanf("%d%d",&h,&g);
            for(int i=1;i<=1<<(h+1);i++)a[i]=0;
            ans.clear();
            for(int i=1;i<=(1<<h)-1;i++)scanf("%d",&a[i]);
            int limit=(1<<g)-1;
            for(int i=1;i<=(1<<g)-1;i++)
            {
                while(getid(i)>limit)
                {
                    ans.push_back(i);
                    dfs(i);  
                }
            }
            ll sum=0;
            for(int i=1;i<=(1<<g)-1;i++)sum+=a[i];
            printf("%lld
    ",sum);
            for(int i=0;i<ans.size();i++)printf("%d%c",ans[i],i==ans.size()-1?'
    ':' ');
        }
        return 0;
    }
    View Code
  • 相关阅读:
    TP3.2写上下篇
    TP3.2写分页
    TP3.2写提交的验证码验证
    thinkphp5.0学习笔记(四)数据库的操作
    thinkphp5.0学习笔记(三)获取信息,变量,绑定参数
    Windows下用Composer引入官方GitHub扩展包
    glog的安装使用
    实现strStr()函数
    何时将析构函数声明为私有?
    memcpy内存重叠
  • 原文地址:https://www.cnblogs.com/MZRONG/p/12656393.html
Copyright © 2011-2022 走看看