通过一段时间的学习,对贪心算法有了一些了解,总结一下学习心得;
贪心算法(又称贪婪算法)是指,在问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解(来自百度百科,哈哈哈)。
上面的说法是肯定是特别准确是表述了贪心算法,下面用一个例子说一下自己对贪心算法的简单认识。假如妈妈给了你一些钱让你去买大米,不论大米的品质,让你尽可能的多买大米。咱们应该怎样买呢?想要多买大米,肯定要买价钱便宜的大米,这时候就肯定要问老板什么大米单价最低,如果单价最低的大米买完了,下面肯定就要买单价第二低的米了,下面就依次类推,直到钱花完为止。
说白了贪心算法就是采取一种方法,尽可能把结果变好。
下面放一些贪心算法的例题:
Saving HDU
悼念512汶川大地震遇难同胞——老人是真饿了
今年暑假不AC
发工资咯:)
无题
稳定排序
迷瘴
下面是贪心算法+优先队列:
看病要排队
湫湫系列故事——消灭兔子
贪心算法学习解题思路+心得:
贪心算法的题一般都要用结构体存储数据+快排,要是不懂结构体和快排怎样使用的,点击这里!!!
利用结构体+快排可以解决大部分贪心算法题的基本问题,其中结构体是用来存储数据的,遇到题可以多想想用结构体存储哪些数据(这个一般比较容易想到),下面就是按结构体里面的某一项进行排序了。当然快排只是对数据进行排序的一种手段,也可以利用其他的排序方法进行排序,不过利用快排函数(sort)比较方便,这里推荐使用这种方法,因为快排函数可以先不了解怎样用代码实现,只需要会调用快排函数对结构体排序就行。想了解快排函数怎样堆结构体排序的,点击这里!!!
当然仅仅利用结构体和快排肯定只能解决一部分问题,如果你会了结构体+快排,你就变成了入门小白了(有贪心算法有了一定的认识),下面就要打怪升级了(刷题不能停!!!)。当然打怪升级过程中,会遇到一个问题,发现小怪一刀一个,大一点怪怎么打都打不过了(难到怀疑人生),这就到了升级的瓶颈期,这时候就需要自己鸟枪换炮了(学会优先队列又能解决一些贪心算法的问题),当自己拿到炮之后又能继续打怪升级了(太爽了!!!)。当然自己以后肯定还会自己无法逾越的大山,用自己的炮还是干不过别人,还是需要继续换更好的装备。。。。。。(我目前没有更好的装备了,要是想更进一步,您去其他的大师那去求学吧,在我这您出师了,哈哈哈)
学习某种学习算法首先肯定是要搞懂某种算法是啥,然后找一道经典的例题,彻彻底底的搞懂这道题是怎样利用某种算法实现这道题的,最好先演草纸是模拟一边代码的实现过程。
放在最前面说的话:我们为啥要要学优先队列,学会优先队列之后可以干啥???
1.顾名思义,优先队列也是队列,也有队列的基本特征,只不过比较特殊,入队的数他会按着从大到小或者从小到大的顺序进行自动排列(你说神奇不神奇),要说他这个优先队列他怎么实现这个自动排序的功能(这个俺也不懂,哈哈哈),但是俺会使用。
又有人问了,如果让结构体定义的变量入队,那这个优先队列他按结构体里面的哪个变量进行排序呢??
这个问题特别好,因为这点特别容易混淆,这一点一会会特别强调,要特别留意!!!
想学会学习优先队列的使用方法,就要首先学会队列的使用方法,不会的话,点击这里!
下面进入优先队列专题:
#include
priority_queue<结构类型> 队列名;
如果是定义一个存放整型数的优先队列,常用的方法是:
priority_queue
q; 入队的数会按着从大到小的规则自动排序,依次由队头排到队尾(太神奇了,你要是不信,自己可以写一个简单的程序验证一下,绝对没骗你),至于为啥是从大到小,下面就说:
priority_queue
,less > p; priority_queue ,greater > q; 上面这两种都定义了两个优先队列,<>里面的第一个int是数据类型,后两个基本用不到,不过less的话,定义的优先队列会从大到小的自动排序,默认的就是这种;greater对应的就是从小到大的优先队列。如果采取这种定义方法要注意后面的两个“>”之间要用空格隔开。
三、优先队列的函数
1.q.size();//返回q里元素个数 2.q.empty();//返回q是否为空,空则返回1,否则返回0 3.q.push(k);//在q的末尾插入k 4.q.pop();//删掉q的第一个元素 5.q.top();//返回q的第一个元素
上面五个函数和基本队列的函数不全一样,可以对比记忆。
讲完了基本使用,自己都可以写一个程序来验证一下,这要好说服自己记住这些知识。
下面说说结构体的优先队列怎样用:
如果结构体里面有好几个数据,那按照那个数据来自动排序呢?
这时候就需要我们的重载函数现身了(重载函数有多种写法,我这种写法是我认为比较好理解的)
struct dd
{
int x,y;
friend bool operator < (dd a,dd b)
{
return a.x>b.x;
}
};
上面的代码定义了一个名为dd的结构体,结构体里有两个整数x和y,这些大家可能都知道,那剩下的的干啥的呢?
friend是用友元函数的是要写的,不懂也没事,记住就完事了,后面的是bool类型,operator和<是来重载”<“用的,那为啥要重载"<",因为我们优先队列有自动排序的动能,但是如果是结构体的优先队列,他按结构体里面的那个元素进行排序呢?这个重载”<“就是来解决这个问题的,下面继续说上面的代码
如果用上面的代码定义一个优先队列,那么优先队列就会以x从小到大自动排序,如果改为小于号,就会按照从大到小规则自动排序,这一点要特别留意。如果用这个结构体(包含了友元函数)定义一个数组,采取sort排序的话,这个顺序刚好和优先队列一反,下面我放一下测试的例子,自己可以写一些简单的例子验证一下。
#include
#include
using namespace std;
struct dd
{
int x,y;
friend bool operator < (dd a,dd b)
{
return a.x>b.x;
}
}k;
priority_queue q;
int main()
{
k.x=10,k.y=20,q.push(k);
k.x=50,k.y=10,q.push(k);
k.x=40,k.y=90,q.push(k);
while(!q.empty())
{
dd s=q.top();
q.pop();
cout<
运行结果:
上面这个例子就是按x从小到大自动排列,下面写一下如果结构体里面写这个友元函数,采取快排函数(测试数据和上面的一样)有什么效果。
#include
#include
#include
using namespace std;
struct dd
{
int x,y;
friend bool operator < (dd a,dd b)
{
return a.x>b.x;
}
}a[10];
priority_queue q;
int main()
{
int i;
cout<<"请输入三组数据:"<>a[i].x>>a[i].y;
sort(a,a+3);
cout<<"排序后三组数据:"<
运行结果:
当然结构体采取快排函数的话,可以不在函数里面写友元函数,可以在外面写一个比较函数,这两种方法均可,不会的话,点击这里!!。
如果里面也写了,外面也写了,刚好这两种规则相反,而且采取的是sort(1,2,3)这种的,第三个写的是自己在结构体外面写的函数名,他会按照你在外面写的函数规则机型排序,这一点自己可以验证一下。
以上就是优先队列的用方法。既然看到底了,何不点个赞再走(你说是吧)