• 优先队列和堆


    能够完成下列操作的数据结构叫做优先队列

    1.插入一个数值

    2.取出最小的数值(获得数值并且删除)

    能够使用二叉树高效地解决上述问题的,是一种叫做“堆”的数据结构。(二叉堆)

    “堆”最重要的性质就是儿子的值一定不小于父亲的值。除此之外,树的节点是按照从上到下,从左到右的顺序紧凑排列的。

    向堆中插入数值时,首先在堆的末尾插入该数值,然后不断向上提升直到没有大小颠倒为止。

    从堆中删除最小值时,首先把堆的最后一个节点的数值复制到根节点上,并且删除最后一个几点。然后不断向下交换直到没有大小颠倒为止。

    在向下交换的过程中,如果有2个儿子,那么选择数值较小的儿子(如果儿子比自己小)进行交换。

    每个操作的复杂度为O(logn)

    下面是堆的实现

     1 const int max_n=1001;
     2 int heap[max_n],sz=0;
     3 void push(int x)
     4 {
     5     //自己节点的编号
     6     int i=sz++;
     7     while(i>0)
     8     {
     9         //父亲节点的编号
    10         int p=(i-1)/2;
    11         //如果已经没有大小颠倒则退出
    12         if(heap[p]>=x) break;
    13         //把父亲节点的数值下放,自己上提
    14         heap[i]=heap[p];
    15         i=p;
    16     }
    17     heap[i]=x;
    18 }
    19 
    20 int pop()
    21 {
    22     //最小值(树根)
    23     int ret=heap[0];
    24     //要提到根的数值
    25     int x=heap[--sz];
    26     //从根开始向下交换
    27     int i=0;
    28     while(i*2+1<sz)
    29     {
    30         //左儿子,右儿子
    31         int a=i*2+1,b=i*2+2;
    32         if(b<sz&&heap[a]>heap[b]) a=b;
    33         //如果没有大小颠倒则推出
    34         if(heap[a]>=x) break;
    35         //把小儿子的数值提上来
    36         heap[i]=heap[a];
    37         i=a;
    38     }
    39     heap[i]=x;
    40     return ret;
    41 }
    heap

    看下之前用贪心法解的一道题   http://www.cnblogs.com/wangkaipeng/p/6425569.html

    农夫约翰为了修理栅栏,要将一块很长的木板切割成n块。准备切成的木板的长度为l1,l2,...,ln。未切割前木板的长度恰好为切割后木板长度的总和。每次切断木板时,需要的开销为这块木板的长度。求按要求切完的最小开销。只说明了大概意思。

    用优先队列实现如下。方便不少。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<memory.h>
     4 #include<queue>
     5 #define INF 10000000
     6 using namespace std;
     7 const int max_n=1001;
     8 int ans=0;
     9 int L[max_n];
    10 int n;
    11 int main()
    12 {
    13     cin>>n;
    14     //从小到大取出数值的优先级队列,可将greater改为less,即为从大到小
    15     priority_queue<int,vector<int>,greater<int> > q;
    16     for(int i=0;i<n;i++)
    17     {
    18         cin>>L[i];
    19         q.push(L[i]);
    20     }
    21     while(q.size()>1)
    22     {
    23         //取出最短木板和次短木板
    24         int l1=q.top();
    25         q.pop();
    26         int l2=q.top();
    27         q.pop();
    28 
    29         //合并木板
    30         int l=l1+l2;
    31         ans+=l;
    32         q.push(l);
    33     }
    34     cout<<ans<<endl;
    35     return 0;
    36 }
    View Code

    poj2431

    为方便输入数据的加油站到终点的距离改为从起点到加油站的距离。

    “可以认为在到达加油站i时,就获得了一次在之后的任何时候都可以加Bi单位汽油的权利”

    因为希望到达终点时加油次数尽可能少,所以当燃料为0之后再进行加油。(选最大的Bi)。用优先队列实现。

     1 #include<bits/stdc++.h>
     2 #define INF 10000000
     3 using namespace std;
     4 const int max_n=1001;
     5 int ans=0;
     6 int A[max_n];
     7 int B[max_n];
     8 int n,l,p;
     9 int main()
    10 {
    11     priority_queue<int> q;
    12     cin>>n>>l>>p;
    13     for(int i=0;i<n;i++)
    14     {
    15         cin>>A[i];
    16     }
    17     for(int i=0;i<n;i++)
    18     {
    19         cin>>B[i];
    20     }
    21     //把终点也当成加油站
    22     A[n]=l;
    23     B[n]=0;
    24     //记录当前位置
    25     int pos=0;
    26     for(int i=0;i<n;i++)
    27     {
    28         //达到下一个加油站的距离
    29         int d=A[i]-pos;
    30         //油量无法到达
    31         while(p-d<0)
    32         {
    33             if(q.empty())
    34             {
    35                 puts("-1");
    36                 return 0;
    37             }
    38             //选择一个油量最多的加油
    39             p+=q.top();
    40             q.pop();
    41             ans++;
    42         }
    43         p-=d;
    44         pos=A[i];
    45         q.push(B[i]);
    46     }
    47     cout<<ans<<endl;
    48     return 0;
    49 }
    View Code
  • 相关阅读:
    day38 20-Spring与Junit整合
    day38 19-Spring整合web开发
    day38 18-Spring的XML和注解的结合使用
    day38 17-Spring的Bean的属性注入:注解方式
    day38 16-Spring的Bean的装配:注解的方式
    day38 15-Spring的配置文件引入的问题
    day38 14-Spring的Bean的属性的注入:集合属性的注入
    day38 13-Spring的Bean的属性的注入:SpEL注入
    day38 12-Spring的Bean的属性的注入:名称空间p
    SqlServer与.NET的数据类型映射关系图
  • 原文地址:https://www.cnblogs.com/wangkaipeng/p/6433930.html
Copyright © 2020-2023  润新知