Introduction (合并果子 题解)堆与贪心 Heap and greedy algorithm

堆与贪心算法的互换

洛谷看题
----------题解区----------
fruit.cpp,贪心 O(nlog(n))
(by作者)关注“fruit”卡片以查看代码
本人码风自认为蛮好,简短、效率高
fruit.cpp,堆(from洛谷网友)
----------废话区----------
没错!上来先给你个题!惊不惊喜意不意外?!


这题本是堆的经典例题,可是经过分析这题也可以用贪心解决,而且很多题也是如此,这是为啥呢?
嗯… 先往下看吧!

说出来你可能不信, 堆一般作为贪心的实现方法,用堆只是便于贪心的计算,可以用堆的维护,来实现贪心的步骤推进。
下面给个堆的类模板

template
/*本模板实例:基础值,每次减少值
维护:基础值减减少值 */ 
class dataheap{
    public:
        T a,b;
        dataheap(T _a;T _b){
            a=_a;
            b=_b;
        }
        void getnew(){
        	a-=b;
		}
}

可见用堆就可以便于对贪心计算时的维护,所以当大家用贪心的话写个class不但代码简单,效率还高。

那为毛从贪心还分出个堆呢?

哈哈哈!看来你对概念不熟悉啊!
贪心是算法,堆是数据结构。

所以还是好好学堆吧。

本附录献给打不开代码的人,别人无需看









附录1:fruit.cpp,贪心

#include
//cout  cin 
#include
//stable_sort()
#include
//class vector
using namespace std;
int N;
vectora;
int hp;
int frist,last;
int main(){
	cin>>N;
	for(int i=0;i>hp;
		a.push_back(hp);
	}
	hp=0;
	/*此题为堆的经典例题,本程序
	演示的是由堆计算到贪心算法的
	一般性方法*/
	/*先取最小两个,合并,记录,
	把合出的分类记录,删除先取的
	最小两个*/ 
	for(int i=0;ia一般(见程序)几乎有序
		所以用sort(O(n^2))会超时,stable_sort(归并排序)
		排序相对稳定*/
		hp+=(a[0]+a[1]);
		a.push_back(a[0]+a[1]);
		a.erase(a.begin());a.erase(a.begin());
	}
	cout<

附录2:fruit.cpp,堆

#include
//作者插嘴:这头文件大家得戒掉
//,以后写项目会影响程序的可读
//性甚至在有些IDE(比如DEV)会加
//大EXE的大小
using namespace std;
const int maxn=10000+10;
int n,heap[maxn],size=0;
void up(int p) //二叉小根堆向上调整(子节点小于父节点就调整)
{
  while(p>1)
  {
    if(heap[p]>n;
  for(int i=1; i<=n; i++)
  {
    int a; cin>>a;
    insert(a); //建立二叉堆
  }
  long long ans=0; //其实这里不会越界,但好像原题数据是3万
  while(size>=2) //如果还可合并
  {
    int top1=gettop(); //取出堆顶(堆中最小值)后删除堆顶
    extract();
    int top2=gettop(); //同上
    extract();
    ans+=(top1+top2);
    insert(top1+top2); //将两数之和加入二叉堆,重复运算
  }
  cout<
看到这了?好孩子!

你可能感兴趣的:(Introduction (合并果子 题解)堆与贪心 Heap and greedy algorithm)