上次讲了堆,别人都说极其简单,我却没学过,今天又听dalao们讲图论,最短路又用堆优化,问懂了没,底下全说懂了,我???,感觉全世界都会了堆,就我不会,于是我决定补一补;

——————来自百度百科

所以,堆其实就是一棵树;

大根堆:根节点比子节点权大;

小根堆:根节点比子节点权小;

了解到了这里,我觉得可以开始做题了;

T1合并果子

题面自己去洛谷看(我懒)

就是一个小根堆,每次取最小的两堆果子合并,排序会tle,所以用堆做,每次把合并后的再加入堆中就行了;

为了练习,先来一个手写堆;

详细看代码:

#include<iostream>
#include<cstdio>
#include<cctype>
#include<cmath>
using namespace std;
inline int read()
{
int x=,f=;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return x*f;
}
int dui[],n,m,ans;
inline void down(int x)
{
if(x*<=n)
{
int t=x;
if(dui[x]>dui[x*])t=x*;
if(dui[x]>dui[x*+]&&x*+<=n&&dui[x*+]<dui[x*])t=x*+;
if(x==t)return;
swap(dui[x],dui[t]);
down(t);
}
}
inline void up(int x)
{
if(x>)
{
if(dui[x]<dui[x/]){
swap(dui[x],dui[x/]);
up(x/);
}
}
}
inline int top(){return dui[];}
inline void delet()
{
dui[]=dui[n];
dui[n--]=;
down();
}
inline void add(int x)
{
dui[++n]=x;
up(n);
}
int main()
{
m=read();
for(int i=;i<=m;i++)
{
int a=read();
add(a);
}
for(int i=;i<m;i++)
{
int x=top();
delet();
int y=top();
delet();
ans+=(x+y);
add(x+y);
}
cout<<ans<<endl;
return ;
}
 #include<iostream>
#include<cctype>//为了用isdigit
#include<cstdio>
using namespace std;
inline int read()//快读(isdigit用来判读入的是否是数字,据说比c>'0'这样的快) ;
{
int x=,f=;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return x*f;
}
int n,dui[],size;//dui用来存堆,size记录元素个数;
inline void swap(int &a,int &b){int t=a;a=b;b=t;return;}//交换值,&直接取地址交换,据说手写更快;
inline void up(int i)//把堆里元素向上移动
{
while(i>)//直到查询到堆顶
if(dui[i]<dui[i/])//如果i的元素比它父节点小,则交换两个元素;
{
swap(dui[i],dui[i/]);
i/=;//继续向上查询
}
else return;
}
inline void init(int x){dui[++size]=x;up(size);}//插入新的元素,size+1,然后看新元素是否要往上移动;
void down(int i)//向下移动大的元素
{
int s=i*;//i的左儿子
while(s<=size)
{
if(dui[i*+]<dui[i*])s++;//从i的左儿子和右儿子中选择较小的交换
if(dui[i]>dui[s])//如果i的权值比i的儿子的权值大,将i向下移动
{
swap(dui[i],dui[s]);
i=s;s=i*;//注意!!!一定要i=s,我忘了会+1卡了好久,左子树和右子树一定要分清楚!!!
}
else return;
}
}
void shanchu(){dui[]=dui[size--];down();}//合并后删除堆顶元素 ,并将元素向下传递;
int top(){return dui[];}//取出堆顶元素
int main()
{
n=read();
int a;
for(int i=;i<=n;i++)
{
a=read();init(a);
}
long long answer=;
while(size>=)
{
int a1=top();
shanchu();
int a2=top();
shanchu();//取出堆中最小的的两堆果子
answer+=(a1+a2);
init(a1+a2);//将合并后的一堆果子加入堆中
}
printf("%lld\n",answer);
return ;
}

偷懒做法,用STL

 #include<iostream>
#include<set>
using namespace std;
multiset<int>dui;//multiset会自动帮你排序,从小到大,设它是一个堆
int n;
int main()
{
int a;
cin>>n;
for(int i=;i<=n;i++)
{
cin>>a;
dui.insert(a);//把元素放进堆里
}
int ans=;
for(int i=;i<=n-;i++)
{
int a1=*dui.begin();//dui.begin()返回的是地址,*取出地址里的值;
dui.erase(dui.begin());//删除堆顶,用地址传递
int a2=*dui.begin();
dui.erase(dui.begin());
ans+=(a1+a2);
dui.insert(a1+a2);//将合并后的加入堆
}
cout<<ans<<endl;
return ;
}

未完待续,如果我忘了可以催更(虽然没人看我博客)

堆学习笔记(未完待续)(洛谷p1090合并果子)的更多相关文章

  1. Go web编程学习笔记——未完待续

    1. 1).GOPATH设置 先设置自己的GOPATH,可以在本机中运行$PATH进行查看: userdeMacBook-Pro:~ user$ $GOPATH -bash: /Users/user/ ...

  2. linux学习笔记---未完待续,缓慢更新

    做为linux菜鸟,由于work的需要,慢慢的开始接触学习linux. <鸟哥的linux私房菜>学习笔记. 一.基础命令操作 1.显示日期的命令 date 执行date命令后,显示结果为 ...

  3. 【洛谷P1090 合并果子】

    题目描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和.可 ...

  4. 洛谷 P1090合并果子【贪心】【优先队列】

    题目描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和.可 ...

  5. [NOIP2004] 提高组 洛谷P1090 合并果子

    题目描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和.可 ...

  6. 洛谷P1090 合并果子【贪心】

    在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和.可以看出,所 ...

  7. 洛谷P1090——合并果子(贪心)

    https://www.luogu.org/problem/show?pid=1090 题目描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合 ...

  8. jQuery 学习笔记(未完待续)

    一.jQuery概述    宗旨: Write Less, Do More.    基础知识:        1.符号$代替document.getElementById()函数        2.使 ...

  9. oracle-绑定变量学习笔记(未完待续)

    --定义变量SQL> var a number; --给绑定变量赋值SQL> exec :a :=123; PL/SQL procedure successfully completed. ...

随机推荐

  1. codeforces164A

    Variable, or There and Back Again CodeForces - 164A Life is not easy for the perfectly common variab ...

  2. liunx系统下crontab定时启动Scrapy爬虫程序

    定时启动爬虫 # 查看命令得绝对路径 # which scrapy # cd到爬虫得项目目录下 + scrapy命令得绝对路径 + 启动命令 */5 * * * * cd /opt/mafengwo/ ...

  3. [线性代数] 线性代数入门A Gentle Introduction

    An Overview: System of Linear Equations Basically, linear algebra solves system of linear equations ...

  4. expect 实例

    [root@runstone ssh_lianxi]# cat expect.sh #!/usr/bin/env expect } { #判断命令行参数的个数 send_user "usag ...

  5. 命令行启动模块的Python代码研究

    pyrasite的 __requires__ = 'pyrasite==2.0' import re import sys from pkg_resources import load_entry_p ...

  6. Mysql -- The used SELECT statements have a different number of columns

    这是因为使用union的两个SQL语句产生的记录的表结构不一致. 必须是结构完全一致的记录集合才可以使用UNION. 以上就是两个表的字段不一样,导致,所以大家可以检查下. 可以 将 select * ...

  7. Tosca new project Repository as MS SQL Server

    # 然后对应的服务器就能自己给创建对应的数据库

  8. ubuntu下载自带的java-1.8

      1.如果是自带的openjdk运行下面可以删除: sudo apt-get purge openjdk* 但是这种情况又不一定成功,有时候运行java -version发现还是可以运行的.证明删除 ...

  9. SQL-W3School-函数:SQL NOW() 函数

    ylbtech-SQL-W3School-函数:SQL NOW() 函数 1.返回顶部 1. NOW() 函数 NOW 函数返回当前的日期和时间. 提示:如果您在使用 Sql Server 数据库,请 ...

  10. ISO/IEC 9899:2011 条款5——5.1.2 执行环境

    5.1.2 执行环境 1.定义了两个执行环境:独立式(freestanding)以及宿主的(hosted).在这两种情况下,当一个派定的C函数被执行环境调用时,程序就启动.所有具有静态存储周期的对象应 ...