贪心算法

动态规划和贪心算法的区别

£可爱£侵袭症+ 提交于 2020-01-20 16:18:58
这是转别人的,待会我会自己总结 动态规划和贪心算法的区别 动态规划和贪心算法都是一种递推算法 均有局部最优解来推导全局最优解 不同点: 贪心算法: 1.贪心算法中,作出的每步贪心决策都无法改变,因为贪心策略是由上一步的最优解推导下一步的最优解,而上一部之前的最优解则不作保留。 2.由(1)中的介绍,可以知道贪心法正确的条件是:每一步的最优解一定包含上一步的最优解。 动态规划算法: 1.全局最优解中一定包含某个局部最优解,但不一定包含前一个局部最优解,因此需要记录之前的所有最优解 2.动态规划的关键是状态转移方程,即如何由以求出的局部最优解来推导全局最优解 3.边界条件:即最简单的,可以直接得出的局部最优解 ============================================================================== 来源: https://www.cnblogs.com/nwpuzzh/p/3926049.html

算法设计方法概览

僤鯓⒐⒋嵵緔 提交于 2020-01-19 00:49:21
算法设计方法概览 文章目录 算法设计方法概览 递归算法 什么是递归 定义及分类 直接递归 间接递归 尾递归 使用场景 递归模型 递归算法设计 递归与数学归纳法 第一数学归纳法 第二数学归纳法 递归算法设计的一般步骤 分治算法 分治法概述 使用场景 分治法的求解过程 蛮力法 蛮力法概述 使用场景 回溯法 问题的解空间 概述 种类 什么是回溯法 使用回溯法的一般步骤 分枝限界法 什么是分枝限界法 分枝限界法的设计思想 1. 设计合适的限界函数 2. 组织活结点表 3. 确定最优解的解向量 采用分枝限界法的三个关键问题 贪心法 贪心法概述 贪心法应用约束 贪心选择性质 最优子结构性质 动态规划 动态规划的原理 动态规划求解的基本步骤 动态规划与其他方法的比较 递归算法 什么是递归 定义及分类 直接递归 在定义一个过程或者函数时,出现调用本过程或本函数的成分,称之为递归。如果调用自身,称之为直接递归; 间接递归 若过程或者函数p调用过程或者函数q,而q又调用p,称之为间接递归; 任何间接递归都可以等价地转换为直接递归; 尾递归 如果一个递归过程或递归函数中递归调用语句是最后一条执行语句,则称这种递归为尾递归; 使用场景 可以使用递归解决的问题,应该满足以下三个特点: 需要解决的问题可以转换为一个或多个子问题来求解,而这些子问题的求解方法和原问题完全相同,只是数据规模不同;

算法设计与分析

☆樱花仙子☆ 提交于 2020-01-15 01:35:56
一、算法思想 (一)分治法(divide and conquer method) 是将待求解的原问题划分成k个较小规模的子问题,对这k个子问题分别求解。如果子问题的规模仍然不够小,则再将每个子问题划分为k个规模更小的子问题,如此分解下去,直到问题规模足够小,很容易求出其解为止(子问题求解思路一致),再将子问题的解合并为一个更大规模的问题的解,自底向上逐步求出原问题的解。 (二)动态规划法(dynamic programing method) 是将待求解问题分解成若干个相互重叠的子问题,每个子问题对应决策过程的一个阶段,一般来说,子问题的重叠关系表现在对给定问题求解的递推关系(也就是动态规划函数)中,将子问题的解求解一次并填入表中,当需要再次求解此子问题时,可以通过查表获得该子问题的解而不用再次求解,从而避免了大量重复计算。 (三)贪心法(greedy method) 贪心法在解决问题的策略上目光短浅,只根据当前已有的信息就做出选择,而且一旦做出了选择,不管将来有什么结果,这个选择都不会改变。换言之,贪心法并不是从整体最优考虑,它所做出的选择只是在某种意义上的局部最优。这种局部最优选择并不总能获得整体最优解(Optimal Solution),但通常能获得近似最优解(Near-Optimal Solution)。 (四)回溯法(back track method)

动态规划3-贪心算法-0-1背包

拈花ヽ惹草 提交于 2020-01-07 21:28:29
参考 https://zh.wikipedia.org/wiki/%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95 贪心算法 (英语: greedy algorithm),又称 贪婪算法 ,是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的 算法 。 [1] 比如在 旅行推销员问题 中,如果旅行员每次都选择最近的城市,那这就是一种贪心算法。 贪心算法在有最优子结构的问题中尤为有效。最优子结构的意思是局部最优解能决定全局最优解。简单地说,问题能够分解成子问题来解决,子问题的最优解能递推到最终问题的最优解。 贪心算法与 动态规划 的不同在于它对每个子问题的解决方案都做出选择,不能回退。动态规划则会保存以前的运算结果,并根据以前的结果对当前进行选择,有回退功能。 贪心法可以解决一些 最优化 问题,如:求 图 中的 最小生成树 、求 哈夫曼编码 ……对于其他问题,贪心法一般不能得到我们所要求的答案。一旦一个问题可以通过贪心法来解决,那么贪心法一般是解决这个问题的最好办法。由于贪心法的高效性以及其所求得的答案比较接近最优结果,贪心法也可以用作辅助算法或者直接解决一些要求结果不特别精确的问题。 贪心算法,可以针对一些不是特别复杂的问题,也就是不需要推导重来,确定子结构最优解,这个最优解就是最终解的一部分,不会像动态规划中

贪心算法求解汽车加油问题

南楼画角 提交于 2020-01-07 15:28:43
试用贪心算法求解汽车加油问题: 已知一辆汽车加满油后可行驶n公里,而旅途中有若干个加油站。试设计一个有效算法,指出应在哪些加油站停靠加油,使加油次数最少,请写出该算法: 1 int greedy(vector<int>x,int n)//定义一个int类型的向量x 2 { 3 int sum=0,k=x.size();//求k为x的长度 4 for(int j=0;j<k;j++) 5 { 6 if(x[j]>n) //加一次油最多行驶n公里,超过的话油不够使,车停在半路上了。 7 { 8 cout<<"NO Solution"<<endl; 9 return -1; 10 } 11 } 12 for(int i=0,s=0;i<k;i++) 13 { 14 s+=x[i]; //s是加一次油在可行范围内行驶的路程,比如加油站相离比较近,我可以多过几个加油站再加油。 15 if(s>n) //如果s>n,就需要加油啦! 16 { 17 sum++;s=x[i]; //sum是加油的次数 18 } 19 } 20 return sum; //函数值返回的结果是加油的次数 21 } 来源: https://www.cnblogs.com/ma1998/p/12148240.html

贪心算法

拜拜、爱过 提交于 2020-01-07 14:33:04
总在做出当前看起来最好的选择,一些情况下即使不能得到整体最优解,但最终结果是最优解的很好的近似解 贪心选择的基本要素 贪心选择性质:所求问题的整体最优解可以通过一系列局部最优的选择来达到 最优子结构性质:一个问题的最优解包含其子问题的最优解 背包问题 与0-1背包问题类似,所不同的是,在选择物品i装入背包的时候,可以选择物品i的一部分装入背包,而不一定全部装入背包,这是与0-1背包问题的差别 算法思路 把物品按照单位价值进行非降序排列,从单位价值最高的物品开发放,能放则全部放入,否则放入他能放入的部分 代码实现 使用物品类代表每个物品 static class Produce { float weight ; //重量 float value ; //价值 float wv ; //单位价值 v/w float x ; //放多少 int index ; //编号 Produce ( float weight , float value , int index ) { this . weight = weight ; this . value = value ; this . index = index ; this . wv = value / weight ; } } 使用物品数组存储物品 static Produce [ ] produces ;

POJ 3069 Saruman's Army(贪心+区间覆盖)

我与影子孤独终老i 提交于 2020-01-02 04:09:07
原题地址 http://poj.org/problem?id=3069 题意:X轴上有n个点Xi,雷达必须被放置在点上,且能探测与其距离为R内的所有点,求能覆盖所有点的最少雷达数。 解题思路 这题属于贪心算法的题目,很明显也是区间覆盖问题。 我也是愚蠢到极致了,才会想着记录每个点的R范围内的邻居数,对邻居数降序排,在邻居数最多的点上放雷达。浪费了一个半小时,数组套数组,还是WA,debug失败只能参考大神的博客。 看了大神的解释,醒悟到这题与上一篇 POJ 2586 应该是同一种思路,即 让特殊点的影响尽量向后面辐射,来减少之后摆放标记点的数目。 贴一下大神的博客: POJ3069 POJ2586 解题报告(异曲同工的贪心算法) 总结一下外层while循环里执行的任务: 从左到右看,选择需要被新雷达覆盖的最左点xi 找到[xi, xi+R]内最靠右的点,放置新的雷达 找到新雷达Xj辐射范围[xj, xj+R]内的最靠右的点,其下一个点就是下一个雷达要覆盖的最左点 AC代码 #include <iostream> #include <algorithm> using namespace std; int main() { int a[1001]; int R,n; while (cin >> R >> n) { if (R == -1 && n == -1) break; for

C语言--贪心思想初级题

大憨熊 提交于 2020-01-01 01:24:23
利用贪心算法思想解决一些小问题 有一艘船,荷载100公斤,有n个人,体重不一,要过河,问船要几趟才能运完这些人。 解决思路:将这些人体重排个序,每次取最小的一个跟最大的一个一起坐船,小于荷载就一起走,不小于就体重大的那个一个人走。 # include <stdio.h> int main ( ) { printf ( "请输入最大荷载,渡船人数,每个人的体重!\n" ) ; int m , n ; int i , j ; int arr [ 20 ] = { 0 } ; scanf ( "%d %d" , & m , & n ) ; for ( i = 0 ; i < n ; i ++ ) { scanf ( "%d" , arr + i ) ; } //先对体重排序,从小到大 for ( i = 0 ; i < n - 1 ; i ++ ) { for ( j = 0 ; j < n - 1 - i ; j ++ ) { if ( arr [ j ] > arr [ j + 1 ] ) { int tmp = arr [ j ] ; arr [ j ] = arr [ j + 1 ] ; arr [ j + 1 ] = tmp ; } } } for ( i = 0 ; i < n ; i ++ ) { printf ( "%d " , arr [ i ] ) ; } int

贪心算法----区间选点问题(POJ1201)

允我心安 提交于 2019-12-31 11:13:05
题目:      题目的大致意思是,给定n个闭区间,并且这个闭区间上的点都是整数,现在要求你使用最少的点来覆盖这些区间并且每个区间的覆盖的点的数量满足输入的要求点覆盖区间的数量。   输入:     第一行输入n,代表n个区间。     接下来的n行每行的第一个数代表区间起点,第二个数代表区间终点,第三个数代表这个区间必须要选取的点的数量。   输出:     输出最少的点的数量,这些最少的点要覆盖全部区间。   这个题是区间选点问题的一种变体,但是我们对于区间选点问题清楚之后那么这种题目也是一样解决的,只不过需要在某些地方特别处理一下。这道题目跟区间调度的问题非常类似,我们也可以采用区间调度问题的策略运用到这道题目上面,尽量往结束时间的端点来选点因为这样做我们可以使尽量少的点覆盖更多的区间,之后就是选点的问题了,当我们选择了这个点之后需要标记一下,定义一个数轴来记录其中标记过的点,以防下一次在选点的时候重复选择。而且在for循环中依次扫描这些给定的区间,看这个区间需要覆盖的点的数量是多少(有可能这个区间的标记的点出现在另外的区间上那么这个时候我们就选择跳过这个点)    代码: 1 import java.util.Arrays; 2 import java.util.Scanner; 3 4 public class 区间选点问题1 { 5 public static void

贪心算法小例子

别来无恙 提交于 2019-12-28 03:34:12
* 贪心算法介绍: 贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。 贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。 问题 给定一个整数数组nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 示例: 输入:[-2,1,-3,4,-1,2,1,-5,4]; 输出:6 解释:连续子数组[4,-1,2,1]的和最大,为6。 贪心算法解法 java 源代码: class Solution{ public int maxSubArray(int[] nums){ int n=nums.length; int currSum=nums[0], maxSum=nums[0]; for(int i=1;i<n;++i){ currSum=Math.max(nums[i],currSum+nums[i]); maxSum=Math.max(maxSum,currSum); } renturn maxSum; } } 时间复杂度:o(N),只遍历了一次数组;空间复杂度:o(1),只使用了常数空间。 贪心算法感悟 该算法使用循环遍历的方法分步求每当前最大的结果