算法进阶 笔记1 (贪心算法)

贪心算法

贪心,顾名思义就是只考虑当前的利益,关注的是局部最优解。
在这里插入图片描述


1、找零问题

在这里插入图片描述
要找零376,贪心算法先从最大面额的100开始找,找不开再接着50,以此类推。

t = [100, 50, 20, 5, 1]
def change(t, n):
	m = [0 for _ in range(len(t))]
	for i, money in enumerate(t):
		m[i] = n // money
		n = n % money
	return m, n

print(change(t, 376))

2、背包问题

在这里插入图片描述
在这里插入图片描述
单位重量的价格分别为6,5,4,商品1,2,3可以分别看作金,银,铜。贪心算法首先拿最值钱的,所以拿的商品顺序是从上到下拿。如果是0-1背包,则先拿商品1,再拿商品2,只有20容量了,放不下商品3,总共价值160。而如果不用贪心算法,拿商品2和商品3,价值220。可见这里0-1背包得不到最优解。分数背包则一定能得到最优解,因为最后背包空间一定能够装满。

分数背包代码实现:

goods = [(60,10),(100,20),(120,30)]		# 每个商品元组表示(价格,重量)
goods.sort(key=lambda x: x[0]/x[1], reverse=True)

def fractional_backpack(goods, w):
	m = [0 for _ in range(len(goods))]
	total_v = 0
	for i, (prize, weight) in enumerate(goods):
		if w >= weight:
			m[i] = 1 
			total_v += prize
			w -= weight
		else:
			m[i] = w / weight
			total_v += m[i] * prize
			w = 0
			break
	return total_v, m

print(fractional_backpack(goods, 50))

3、数字拼接问题

拼接最大数字问题

在这里插入图片描述

# a = "96"
# b = "87"
# a + b if a>b else b + a
# a与b的长度可能不一样,不能直接比,相加后长度一样
# a = "128"
# b = "1286"
# a + b = "1281286"
# b + a = "1286128"
# a + b if a+b>b+a else b + a

from functools import cmp_to_key

li = [32, 94, 128, 1286, 6, 71]

def xy_cmp(x, y):
	if x+y < y+x:
		return 1
	elif x+y > y+x:
		return -1
	else:
		return 0
		
def number_join(li):
	li = list(map(str, li))
	li.sort(key=cmp_to_key(xy_cmp))		# 相当于python2的cmp功能,如果比较函数返回1则交换顺序,从而实现开头数字大的在前面
	return "".join(li)
	
print(number_join(li))

cmp_to_key详解


4、活动选择问题

在这里插入图片描述
在这里插入图片描述

activities = [(1,4),(3,5),(0,6),(5,7),(3,9),(5,9),(6,10),(8,11),(8,12),(2,14),(12,16)]
# 保证活动是按照结束时间排好序的
activities.sort(key=lambda x:x[1])

def activity_selection(a):
	res = [a[0]]
	for i in range(1, len(a)):
		if a[i][0] >= res[-1][1]:		# 当前活动的开始时间小于等于最后一个入选活动的结束时间
			# 不冲突
			res.append(a[i])
	return res

print(activity_selection(activities))

贪心算法总结

以上四个问题共同的特点是都是最优化问题,找零问题找的是钱数量最少,背包问题找的是价值最多,拼接问题找的是整数最大,活动选择问题找的是个数最多。但并不是什么时候都能得到最优解,如背包问题里面的0-1背包就做不到。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天涯小才

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值