贪心算法

LeetCode题解——贪心算法

会有一股神秘感。 提交于 2019-12-01 01:38:32
贪心算法 关于贪心算法,我们先看一个例子。 假设我们有一个可以容纳 100kg 物品的背包,可以装各种物品。我们有以下 5 种豆子,每种豆子的总量和总价值都各不相同。为了让背包中所装物品的总价值最大,我们如何选择在背包中装哪些豆子?每种豆子又该装多少呢? 实际上,这个问题很简单,我估计你一下子就能想出来,没错,我们只要先算一算每个物品的单价,按照单价由高到低依次来装就好了。单价从高到低排列,依次是:黑豆、绿豆、红豆、青豆、黄豆,所以,我们可以往背包里装 20kg 黑豆、30kg 绿豆、50kg 红豆。 这个问题的解决思路显而易见,它本质上借助的就是贪心算法。结合这个例子,我总结一下贪心算法解决问题的步骤,我们一起来看看。 第一步,当我们看到这类问题的时候,首先要联想到贪心算法:针对一组数据,我们定义了限制值和期望值,希望从中选出几个数据,在满足限制值的情况下,期望值最大。 类比到刚刚的例子,限制值就是重量不能超过 100kg,期望值就是物品的总价值。这组数据就是 5 种豆子。我们从中选出一部分,满足重量不超过 100kg,并且总价值最大。 第二步,我们尝试看下这个问题是否可以用贪心算法解决:每次选择当前情况下,在对限制值同等贡献量的情况下,对期望值贡献最大的数据。 类比到刚刚的例子,我们每次都从剩下的豆子里面,选择单价最高的,也就是重量相同的情况下,对价值贡献最大的豆子 第三步

贪心算法

徘徊边缘 提交于 2019-11-30 19:53:35
贪心算法是指,在对问题求解时,总是做出在 当前看来是最好的选择 。也就是说,**不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。**贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择。必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,**即某个状态以后的过程不会影响以前的状态,只与当前状态有关。**所以对所采用的贪心策略一定要仔细分析其是否满足无后效性。 贪心算法的基本思路: 1.建立数学模型来描述问题。 2.把求解的问题分成若干个子问题。 3.对每一子问题求解,得到子问题的局部最优解。 4.把子问题的解局部最优解合成原来解问题的一个解。 贪心算法适用的问题 ** 贪心策略适用的前提是:局部最优策略能导致产生全局最优解。** 实际上,贪心算法适用的情况很少。一般,对一个问题分析是否适用于贪心算法,可以先选择该问题下的几个实际数据进行分析,就可做出判断。 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。 示例 1: 输入: \[7,1,5,3,6,4\] 输出: 7 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5

贪心

Deadly 提交于 2019-11-30 15:11:27
贪心策略,万能算法。 我就后悔当时没有好好学贪心 贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。 贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。 有几个关键词很重要:局部最优,整体最优,无后效性。 无后效性不用了提了吧 显然贪心算法取决于你的贪心策略,局部最优能否推到全局最优,所以在考试时,没有严谨的贪心正确性证明,贪心慎用。 比如 Luogu P1880 [NOI1995]石子合并 坑倒了一堆人。 区间调度问题 在一个数轴上有n条线段,现要选取其中k条线段使得这k条线段两两没有重合部分,问最大的k为多少。 对右端点从小到大O(n logn)排序,O(n)扫一遍就行了 这道题也可以用DP做,通过决策单调性可以优化到O(n) 证明   对于每一条线段之前我们选择的是右端点最小的上一条线段,则这样可以把答案最大化。 来源: https://www.cnblogs.com/soledadstar/p/11600862.html

[一本通学习笔记] 贪心问题

随声附和 提交于 2019-11-30 10:05:49
#LOJ10000. 「一本通 1.1 例 1」活动安排 【题意】 数轴上若干线段,选出最多的线段且它们互不相交。 【思路】 考虑对线段排序。由于要尽可能节约总体右边界,我们以右端点为关键字进行排序,顺序扫描所有区间,如果能将区间加入集合就加入。 也可以考虑对端点离散化后,处理出从每个点开始续一个线段能“跳”到的最近位置,然后模拟跳一下即可。 这里给出后一种思路的代码。 #include <bits/stdc++.h> using namespace std; int s[1005],t[1005],f[2005],n; int main() { cin>>n; for(int i=1;i<=n;i++) cin>>s[i]>>t[i]; map<int,int> mp; for(int i=1;i<=n;i++) { mp[s[i]]++; mp[t[i]]++; } int idx = 0; for(map<int,int>::iterator it=mp.begin();it!=mp.end();it++) it->second = ++idx; for(int i=1;i<=n;i++) { s[i]=mp[s[i]]; t[i]=mp[t[i]]; } for(int i=1;i<=idx;i++) f[i]=idx+1; for(int i=1;i<=n;i++) {

贪心算法之——黑白点的匹配(两种实现方法)

拈花ヽ惹草 提交于 2019-11-30 08:11:28
一、题目 设平面上分布着 n个白点和 n个黑点,每个点用一对坐标( x, y)表示。一个黑点 b=( xb,yb)支配一个白点 w=(xw, yw)当且仅当 xb>=xw和 yb>=yw。 若黑点 b支配白点 w,则黑点 b和白点 w可匹配(可形成一个匹配对)。 在一个黑点最多只能与一个白点匹配,一个白点最多只能与一个黑点匹配的前提下,求 n个白点和 n个黑点的最大匹配对数。 二、解题思路   一看完题目,一开始的思路是先将黑白点分别存入两个数组中,再对两个数组分别进行对x和对y的排序,在实际实验过程中,发现排序完后数组的下标与点不好对应,这样就不容易确定一个点是否已经匹配过。   经过了解查阅后发现了最大匹配问题的算法,和本题类似,而且递归的操作复杂度远小于多次对数组的排序。   而且过多的排序也造成了算法思路难以理清。决定先学习掌握最大匹配度算法再考虑本题…   在查阅了最大匹配度问题的思想后,发现这是一种递归形式的方法,算法需要基于对二分图的遍历算法,这就需要学习DFS或者BFS,所以又去复习了一下这两个算法,在彻底掌握了之后终于可以步入正题了… (dfs和bfs的执行动态图 ) http://5b0988e595225.cdn.sohucs.com/images/20171101/f1f45fe9ca37425ba200180be89624b2.gif http:/

算法面试8---贪心算法

别来无恙 提交于 2019-11-30 06:13:57
1 简单贪心 贪心算法相对来说代码少,思路简单,但贪心问题的关键是确定一个问题能否使用贪心算法去解决。 例1: LeetCode 455。题解:把最大的饼干分给最贪心的还在,那么剩下的饼干中就是次大的分给次贪心的孩子即还是当前最大的饼干分给最贪心的孩子。在贪心算法中,常常要涉及到最大,最小这些数据因此常常需要进行排序。 class Solution { public int findContentChildren(int[] g, int[] s) { Arrays.sort(g); Arrays.sort(s); int i = 0,j = 0; int l1 = g.length,l2= s.length; while (i<l1 && j<l2) { if (g[i] <= s[j]) { i++; //孩子的需求被满足了,可以转到下一个孩子了 } j++; //否则寻找更大的饼干 } return i; //因为i是从0开始的所以直接返回便是满足孩子需求的数目 } } 与此类似题目:LeetCode 392。 2 贪心与动态规划的关系 例1: LeetCode 435。题目中是最少需要移除多少区间使得区间不重叠那么也可以理解为最多保留多少个区间使得区间不重叠。暴力思路就是找出所有的子区间然后判断是否重叠,为了判断重叠时方便可以先进行排序

那些经典算法:贪心算法

天大地大妈咪最大 提交于 2019-11-30 05:35:47
贪心算法和分治算法、动态规划算法、回溯算法都是一种编程思想,深入理解这些编程思想,我们也可以根据实际情况设计自己的算法。 一 贪心算法原理 贪心算法的原理比较简单,就是对问题求解的时候,每步都选择当前的最优解,然后已期望得到全局最优解。 贪心算法的适用场景是每次选择是没有状态的,也就是不会对后面的步骤产生影响。 二 贪心算法举例 同样用老师课件中的两个例子: 背包问题: 假如我们有一个可以装100kg物品的背包,我们有5种豆子,每种豆子的总量和总价值各不相同。为了让背包中所装的物品的总价值最大,我们如何选择装哪些豆子,每种装多少? 分析 直观来想,我们的总重是100kg是限制的,要求装的物品总价值最大,那么我们可以把各种豆子的单价计算下每种豆子的单价,然后按照从高到低排序,每次装完最有价值的豆子后,再继续装稍次价值的豆子,直到装满整个背包。 分糖果: 我们有m个糖果和n个孩子,现在要把糖果分给这些孩子吃,但是糖果少m<n,所以只有一部分孩子能够得到糖果,每个糖果的大小不一样,m个糖果大小分别为s1,s2,s3….sm.除此之外,每个孩子对糖果大小需求不一样,假设这些孩子对糖果的需求大小分别为g1,g2…gn,只有糖果大小大于孩子对糖果需求的时候,他们才会满足,求我们如何分糖果才能够满足最多数量的孩子。 分析: 这个问题是我们选择一部分小孩分给他们糖果,要满足一共最多只能分给m个孩子

面试问题之数据结构与算法:动态规划基本思想

≯℡__Kan透↙ 提交于 2019-11-30 04:32:37
转载于:https://blog.csdn.net/u013250416/article/details/80558542 一、基本思想   一般来说,只要问题可以划分为规模更小的子问题,并且原问题的最优解中包含了子问题的最优解,则可以考虑用动态规划解决。动态规划的实质是分治思想和解决冗余。因此,动态规划是一种将问题实例分解为更小的/相似的子问题,并存储子问题的解,使得每个子问题只求解一次,最终获得原问题的答案,以解决最优化问题的算法策略。 与贪心法的关系: 1.与贪心法类似,都是将问题实例归纳为更小的、相似的子问题,并通过求解子问题产生一个全局最优解。 2.贪心法选择当前最优解,而动态规划通过求解局部子问题的最优解来达到全局最优解。 来源: https://www.cnblogs.com/yichengming/p/11560276.html

剪绳子(贪心算法)

别等时光非礼了梦想. 提交于 2019-11-29 15:04:01
1 #include <iostream> 2 #include <cmath> 3 4 using namespace std; 5 6 /** 7 * 题目分析: 8 * 先举几个例子,可以看出规律来。 9 * 4 : 2*2 10 * 5 : 2*3 11 * 6 : 3*3 12 * 7 : 2*2*3 或者4*3 13 * 8 : 2*3*3 14 * 9 : 3*3*3 15 * 10:2*2*3*3 或者4*3*3 16 * 11:2*3*3*3 17 * 12:3*3*3*3 18 * 13:2*2*3*3*3 或者4*3*3*3 19 * 20 * 下面是分析: 21 * 首先判断k[0]到k[m]可能有哪些数字,实际上只可能是2或者3。 22 * 当然也可能有4,但是4=2*2,我们就简单些不考虑了。 23 * 5<2*3,6<3*3,比6更大的数字我们就更不用考虑了,肯定要继续分。 24 * 其次看2和3的数量,2的数量肯定小于3个,为什么呢?因为2*2*2<3*3,那么题目就简单了。 25 * 直接用n除以3,根据得到的余数判断是一个2还是两个2还是没有2就行了。 26 * 由于题目规定m>1,所以2只能是1*1,3只能是2*1,这两个特殊情况直接返回就行了。 27 * 28 * 乘方运算的复杂度为:O(log n),用动态规划来做会耗时比较多。 29 */

每日一题(LeetCod 376 贪心)

不问归期 提交于 2019-11-29 14:54:44
摆动序列 贪心算法:顾名思义,贪就好了,就要当前可以选择的最好的最好的。 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。 给定一个整数序列,返回作为摆动序列的最长子序列的长度。 通过从原始序列中删除一些(也可以不删除)元素来获得子序列 (我认为这个是非常重要的条件!!!),剩下的元素保持其原始顺序。 示例 1: 输入: [1,7,4,9,2,5] 输出: 6 解释: 整个序列均为摆动序列 示例 1: 输入: [1,7,4,9,2,5] 输出: 6 解释: 整个序列均为摆动序列 示例 2: 输入:[1,17,5,10,13,15,10,5,16,8] 输出:7 解释:这个序列包含几个长度为 7 摆动序列,其中一个可为[1,17,10,13,10,16,8]。 题目转载自 : 原题地址 这个题目是我从今天看的 贪心算法 的视频看到的一个题目,自己先做了一下,发现自己的思路考虑有些问题,终究还是思路不清晰。 老师给讲了一个这个办法,说是 贪心算法的题目可以先试着把结果写出来 ,来看一看这个是否是适用的,是否是 最优的 。如果是,找一找所有 最优解的共同点 ,我们便可以获取一个 正确的解题思路 如下图所示: 图是 示例2 的解题图片。 写出来了,我们便可以清楚的看出来,这道题的算法写的时候