python实现贪心算法的例子

贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择,不从整体最优上考虑,其实求的是在某种意义上的局部最优解。但在某些问题上贪心算法的解就是最优解

1、找零问题

假设要给你找零n元钱,钱币的面额有100元,50元,20元,5元,1元,如何找零使得所需钱币数量最少?

t = [100, 50, 20, 5, 1]
def change(t, n):  
    m = []
    for money in t:
        m.append(n // money)
        n = n % money
    return m, n  #最后剩了n块钱

print(change(t, 281))

在这里插入图片描述

2、背包问题

有n个商品,第i个商品价值vi,重wi千克(输入下标的方法w~i~,上标用x^2^,x2)。希望选取的商品价值尽量高,但背包只能容纳W千克的东西,应该选取哪些商品?

0-1背包: 对于一个商品,要么完整的拿走,要么留下(商品为金条) (动态规划实现)
分数背包: 对于一个商品,可以拿走其中一部分(商品为金砂)

# 分数背包
goods = [(60, 10), (100, 20), (120, 30)]  # 每个商品元祖表示(价格,重量)
goods.sort(key=lambda x: x[0] / x[1], reverse=True)  # 对goods单位价值从大到小排序

def fractional_backpack(goods, w):  # w为能装的最大重量
    m = [0 for _ in range(len(goods))]  # 建立一个和goods一样长的列表
    total_v = 0  # 初始化总价值
    for i,(price, weight) in enumerate(goods):  # 枚举函数,一个一个取,i为索引值
        if w >= weight:
            m[i] = 1
            total_v += price
            w -= weight
        else:  # 取的下一个物品重量大于背包剩余容量
            m[i] = w / weight  # w为背包剩余容量,此时m[i]为一个分数
            total_v += m[i] * price
            w = 0  # 最后背包剩余容量为0,这句代码不写也好像能行,写上便于理解
            break  # 跳出循环
    return total_v, m

print(fractional_backpack(goods,50))

在这里插入图片描述
结果对应排序后的第一个商品拿一个,第二个商品拿一个,第三个商品拿0.666666个,总价值为240.0

3、拼接最大数字问题

有n个非负整数,将其按照字符串拼接的方式拼接为一个整数,如何拼接使得到的整数最大?

from functools import cmp_to_key

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

def xy_cmp(x, y):
    if x+y < y+x:  # 前面是小的数加大的数,比如128和1286得1281286,比1286128小
        return 1
    elif x+y > y+x:
        return -1
    else:
        return 0

def number_join(li):
    li = list(map(str, li))  # 把li列表中的数字转成字符串再变成一个新列表
    li.sort(key=cmp_to_key(xy_cmp))  # cmp_to_key函数返回的参数是xy_cmp函数,不会可以用冒泡排序
    return ''.join(li)  #join函数连接字符串

print(number_join(li))

在这里插入图片描述

4、活动选择问题

假设有n个活动,这些活动要占用同一片场地,而场地在某时刻只能提供一个活动使用,安排哪些活动能使该场地举办活动的个数最多?
贪心结论:最先结束的活动一定是最优解的一部分

# 一个元祖表示一个活动,数字表示开始时间和结束时间
activitives = [(1,4),(3,5),(1,6),(5,7),(3,9),(6,10),(8,11),(8,12),(2,14),(12,16)]
# 保证活动是按照结束时间排序的
activitives.sort(key=lambda x: x[1])  # sort函数会改变原有的列表

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(activitives))

在这里插入图片描述
学习资源

https://www.bilibili.com/video/BV1uA411N7c5?p=87

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值