贪心算法
说在前面,转载的很多好文章都有利于理解贪心,涉及到侵权会删除的!
一、北鼻先来搞清楚概念哇!
较为正式的解释都是这样的:
贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。
贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。
链接:https://leetcode-cn.com/tag/greedy/
来源:力扣(LeetCode)
可以看看这篇,哈哈我觉得讲的好好玩也容易懂
小白带你学贪心算法【作者:脚本之家】
看完了之后大概知道贪心算法是什么了吧!
把整体最优解的问题转化为局部最优解哟
哎呀我也知道,那难点就是在,怎么找局部最优解捏,继续看吧!
二、判断啥时候要用到贪心捏?
首先都说贪心的两大特性是:最优子结构性质和贪心选择性质。
我自己的理解是看到题目:
- 要求最优解(最大最少最多最少最长最短等等)!
- .这个要求的最优解是在某个约束条件下的(比如背包问题的这个包只能装50公斤,纸币的面值和要求的金额,路径的长度等等)。
- 最优解可以化解为局部最优解去求,没错就是这个局部最优解才是重点。
也可以看看这个贪心跟动态规划的区别,我觉得讲得很好。
贪心算法和动态规划的个人理解 作者:(csdn)谁也不知道会怎样
这个是讲动态规划的,先马克!
从零开始学动态规划 作者:houjingyi233
三、来看看贪心的一些简单例子吧!
我自己理解是,做题的时候是看四点:
- 这个要求的最优解是啥?
- 约束条件是啥?
- 可以分解为怎么样的子结构?
- 怎么样才能有这个子结构的最优解?
可以先看看这个博客的前3个经典的例子,比较好理解哟
五大常用算法之三:贪心算法 作者:hust_chen
这里拿第一个举下栗子哈~
看完那个博客对贪心的例子有一定的了解了吧~
注意前三个栗子都是求解之前已经排好序的哟,这也是找最优解的的选择策略。
那现在就来看看了LeetCode上面的题吧!
从简单到中等哈!
按照顺序,仅仅是我自己做过的哈
122 买卖股票的最佳时机||
看看第二个题解,讲得很好喔
1221 分割平衡字符串
55 跳跃游戏
偷懒了,看官方题解吧嘻嘻嘻
四、一个很糙的贪心模板
int greedy(int[] a){
// 要求的最优解,那倒不一定是int型啦
int bestSolution;
// 大噶发现了没有!!循环是一定要有的!!i开始的下标就要看题目而定了
for ( int i=0; i<n; i++ ) {
// 判断x是否满足约束条件
if( isFeasible(xxxx) ){
//做累加或者其他选择的操作
}
}
return bestSolution;
//哎呀我知道很糙很糙,重点就是遍历的时候那个找最优解
//像之前博客里123题,先排好序再遍历就是一种找最优解的方法哈
}
五、扩展
都说prim和kruskal方法求最小生成树是贪心算法里很好的运用哟,也可以一起看看
//求最小生成树
#include "stdafx.h"
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
//prim算法,找跟金钟罩距离最近的新点
struct node
{
double lowcost;//结点的当前最小权重
int adj;//跟结点连接权重最小的结点
bool isin=false;//结点是否被访问过
}Node[100];
//预设的每个结点花费设其无限大
//指结点i和几点j之间(边)的权重/花费
double cost[100][100]