数据结构与算法11:贪心算法
贪心算法介绍:
对问题求解时,总是做出在当前看来最好的选择
基本思路:
建立数学模型来描述问题
把求解的问题分成若干个子问题
对每一个子问题求解,得到子问题的局部最优解
把子问题的解局部最优解合成原来解问题的一个解
贪心策略适用的前提:局部足有策略能导致产生全局最优解。
贪心算法与动态规划算法的主要区别:
动态规划算法通常是自底向上的方式求解子问题,而贪心算法则通过自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心的选择就所求问题简化为规模更小的子问题。
问题描述1:找硬币:
设有n中不同的硬币,现要用这些面值的硬币来找钱,可以使用各种面值的硬币面值{1,2,5,10,20,50,100,500,1000},对任意钱数,设计一个用最少硬币找钱的方法。
def FindClion(V): aviable = [1,2,5,10,20,50,100,200,500,1000] result = [] for i in aviable[::-1]: while(V >= i): V -= i result.append(i) return result V = 98 print(FindClion(V))
问题描述2:活动问题
N个活动,每个活动的开始时间为si,结束时间是fi。如果si>=fj or sj>=fi 则定义两场活动并不冲突。试着找到一种能够找到最多的非冲突活动的集合(S)。也就是无法找到集合S’,使得|S'|>|S|.
S = 1 3 0 5 8 5
F = 2 4 6 7 9 9
def printMaxActivities(acts): n = len(acts) sort_acts = sorted(acts,key=lambda tup:tup[1]) pre = sort_acts[0] print(pre) for curr in sort_acts: if curr[0] >= pre[1]: print(curr) pre = curr acts = [(0, 6), (3, 6), (1, 2), (5, 7), (8, 9), (5, 9)] printMaxActivities(acts)
问题描述3:
如何找到一个最小的数字,数字的位数与数字位数之和给予:
例如: Input: s = 9, m = 2
output:18
def FindSmallest(m , s): if s == 0: if m == 1: print("Smallest number is 0") else: print("Not possible") return if s > m * 9: return result = [0 for i in range(m+1)] s -= 1 for i in range(m-1, 0, -1): if s <= 9: result[i] = s s = 0 else: result[i] = 9 s -= 9 result[0] = s + 1 for i in range(m): print(result[i], end="") s = 20 m = 3 FindSmallest(m, s)
问题描述4:
将一个数组拆分为两个数字,求两个数字的和最小
例 Input:[6 8 4 5 2 3] Output:604 The minimum sum is formed by numbers 358 and 246
import heapq def minSum(a): heapq.heapify(a) num1 = 0 num2 = 0 while(a): num1 = num1 * 10 + heapq.heappop(a) if a: num2 = num2 * 10 + heapq.heappop(a) return num1 + num2 a = [6, 8, 4, 5, 2, 3] print(minSum(a))
问题描述5:
以最小成本去连接一些绳子。
import heapq def ropeCost(ropes): if len(ropes) == 1: return 0 heapq.heapify(ropes) total = 0 while ropes: first = heapq.heappop(ropes) second = heapq.heappop(ropes) local = first + second total += local if not ropes: break heapq.heappush(ropes, local) return total ropes = [4, 3, 2, 6] print(ropeCost(ropes))