算法总结系列(二):贪心法、分治法
算法2——贪心法、分治法
- 贪心法
- 币种统计问题
- 分治法
- 快速排序
贪心法
关键词:局部最优、近似
算法描述:
1)定义初始点
2)从初始点出发,找当前点局部最优解
3)以局部最优解为初始点,找新的局部最优解
4)重复步骤(3),直到获得满足要求的解
这里我们先不讲贪心法的使用条件,放到后面讲。
下面先举一个例子——币种统计问题,来描述基础的贪心法流程
币种统计问题
问题描述:
单位给员工发工资,为了保证取款的张数最少,取工资前要统计出所有职工的工资所需各种币值(100,50,20, 10, 5, 2, 1共7种)的张数。
程序求解(python):
statistic = {'100':0, '50':0, '20':0, '10':0, '5':0, '2':0, '1':0}bal = 2543for val in statistic.keys():val = int(val)num = int(bal / val)statistic['{}'.format(val)] = statistic['{}'.format(val)] + numbal = bal - num * valprint(statistic)
打印结果:
{'100': 25, '50': 0, '20': 2, '10': 0, '5': 0, '2': 1, '1': 1}
当解决了一个问题后,回过头来思考可以发现新的问题:
- 什么条件下使用贪心法可以获得最优解?
问题1
问题具有最优子结构、贪心选择性质
最优子结构:问题的最优解包含子问题的最优解,即问题可以划分为子问题,并且可以通过求子问题的最优解递推地获得问题的最优解。
证明最优子结构:首先能不能划分为子问题还是靠直觉 : ( ,然后设规模为n的问题S有最优解E, A 是之前一步已经得到的局部最优解,假设E-{A}不是S-{A}规模中最优的解:即存在 E’是 S-{A}规模中最优的解,且E’ 不等于 E-{A} , 从而E’并 {A}是S的最优解,显然E’并 {A} 不等于E,与假设E是原问题S的最优解矛盾。所以如果E是S的最优解,则E-{A}也是S-{A}的最优解。以币值问题为例,假设贪心法获得的不是最优解,因为问题要求取款张数最少,则最优解中存在较大的某些币值数量比贪心解多,而贪心法在每一步都是优先选择最大币值,因此最优解中不可能存在较大币值比贪心法多,故假设不成立,最优子结构证毕。这说明问题可以用贪心法获得最优解。
贪心选择:选择当前最优不影响之后的选择
贪心选择我也不知道咋证明(似乎需要用到归纳证明),就举个例子:
同样是上面的币值统计问题,在币值里加入70元,同时要发的工资为140元,你会发现这时贪心法不好使了,最优应该是70* 2,而非100* 1+20* 2。
我的理解就是这个问题需要除最大币值外的所有币值要小于或等于最大币值的1/2,这是这个问题隐含的选择之间互相影响的条件。70*2=140>100,因此不能用贪心法咯。
分治法
关键词:子问题、合并
算法描述:
1)将问题分解为子问题
2)解决子问题
3)合并子问题解
举个栗子:
快速排序
基础流程:
1)设定分界值
2)按照分界值划分数据
3)重复步骤1、2划分分界值两侧数据直到不能划分
程序设计(python):
def quick_sort(alist, start, end):"""快速排序"""if start >= end: # 递归的退出条件returnmid = alist[start] # 设定起始的基准元素low = start # low为序列左边在开始位置的由左向右移动的游标high = end # high为序列右边末尾位置的由右向左移动的游标while low < high:# 如果low与high未重合,high(右边)指向的元素大于等于基准元素,则high向左移动while low < high and alist[high] >= mid:high -= 1alist[low] = alist[high] # 走到此位置时high指向一个比基准元素小的元素,将high指向的元素放到low的位置上,此时high指向的位置空着,接下来移动low找到符合条件的元素放在此处# 如果low与high未重合,low指向的元素比基准元素小,则low向右移动while low < high and alist[low] < mid:low += 1alist[high] = alist[low] # 此时low指向一个比基准元素大的元素,将low指向的元素放到high空着的位置上,此时low指向的位置空着,之后进行下一次循环,将high找到符合条件的元素填到此处# 退出循环后,low与high重合,此时所指位置为基准元素的正确位置,左边的元素都比基准元素小,右边的元素都比基准元素大alist[low] = mid # 将基准元素放到该位置,# 对基准元素左边的子序列进行快速排序quick_sort(alist, start, low - 1) # start :0 low -1 原基准元素靠左边一位# 对基准元素右边的子序列进行快速排序quick_sort(alist, low + 1, end) # low+1 : 原基准元素靠右一位 end: 最后if __name__ == '__main__':alist = [54, 26, 93, 17, 77, 31, 44, 55, 20]quick_sort(alist, 0, len(alist) - 1)print(alist)
代码来源
在快速排序中,每个基准值两侧的数据就是被划分后的子问题,通过递归地求解子问题,最后将解合并获得最终解,体现了分治法的基本思想。
算法总结系列(二):贪心法、分治法相关推荐
- 算法设计与分析-----贪心法
算法设计与分析-----贪心法(c语言) 一.贪心法 1.定义 2.贪心法具有的性质 1.贪心选择性质 2.最优子结构性质 3.贪心法的算法框架 5.求解活动安排问题 6.求解最优装载问题 二. 贪心 ...
- 算法复习笔记(三)分治法
算法复习笔记(三)分治法 1.引入语 分治法划分对策: 子问题与原问题相比:问题性质一致,问题规模不同 求解一般分为三个阶段: 1.划分:直到问题足够小可以直接求解为止 2.求解: 3.合并:将子问题 ...
- 算法设计思想(4)— 分治法
1. 分治法概念 分治,顾名思义,分而治之. 具体来说,它先将一个难以直接解决的大问题,分割成一些可以直接解决的小问题.如果分割后的问题仍然无法直接解决,那么就继续递归地分割,直到每个小问题都可解. ...
- 常用十大算法 非递归二分查找、分治法、动态规划、贪心算法、回溯算法(骑士周游为例)、KMP、最小生成树算法:Prim、Kruskal、最短路径算法:Dijkstra、Floyd。
十大算法 学完数据结构该学什么?当然是来巩固算法,下面介绍了十中比较常用的算法,希望能帮到大家. 包括:非递归二分查找.分治法.动态规划.贪心算法.回溯算法(骑士周游为例).KMP.最小生成树算法:P ...
- 数据结构与算法学习笔记4:递归+分治法
数据结构与算法学习笔记4 递归 斐波那契数列 青蛙跳台阶问题 链表倒序打印 分治法 二分查找/折半查找 Binary Search 题目1:快速幂 题目2:如何判断一个数是否为2的次幂 递归 指在函数 ...
- 算法设计练习题(1)——分治法
1. 给定一个数组A,任务是设计一个算法求得数组中的"主元素",即在数组中个数超过数组总元素个数一半的元素.但是数组中元素的数据类型可能是复杂类型,这意味着数组中的元素进能够比较是 ...
- 【算法设计与分析】关于分治法的一些(伪)代码整理
分治法 合并排序 利用分治法求一个元素在数组中的最大位置 利用分治法求一个n元素数组的最大元素和最小元素的值 是否稳定 快速排序 合并排序 利用分治法求一个元素在数组中的最大位置 伪代码: MaxIn ...
- 算法第五期——贪心法(Python)
目录 贪心法 例子:最少硬币问题 贪心和动态规划 例题:快乐司机 思路:
- Java常用算法二:分治法
文章目录 一.分治算法的基本步骤 二.分治算法解决汉诺塔问题 2.1 汉诺塔的规则: 2.2 使用分治算法 笔记参考:尚硅谷 分治法就是把很复杂的问题分而治之,把一个很大的问题分成几个很小的问题,再把 ...
最新文章
- 一行CSS样式去除百度地图版权,去除百度地图右上角平移缩放控件的市县区文字
- 系统延时任务和定时任务
- python 自定义模块_Python 自定义模块路径
- C:C++ 函数返回多个参数
- 用指针编写程序将输入的字符串倒序输出
- Spring的事务机制
- AMESim找图形平衡点的方法
- MVC5 + EF6 + Bootstrap3 (11) 排序、搜索、分页
- Toggle和Slider组件
- 【总结】操作系统原理
- querydsl动态 sql_SpringDataJPA学习记录(四)--使用QueryDSL
- 【嵌入式模块】ESP8266完整教程
- rollup函数(分组后对每组数据分别合计)
- 《MATLAB语音信号分析与合成(第二版)》:第5章 带噪语音和预处理
- 五子棋-单机游戏-微信小游戏项目开发入门
- 查询快递单号物流,筛选从某地发出的单号
- chrome访问淘宝和京东崩溃,解决方法
- iphone 存图片和视频到iPhone相册
- 手把手教你实现百度基础地图+定位功能+设置中心点+添加Marker
- RFID固定资产管理降低人工成本,实现智能化的管理-新导智能