算法之贪心

文章介绍了贪心算法的概念,通过找零问题、背包问题(包括分数背包和0-1背包)以及拼接最大数字和活动选择问题等实例,展示了如何利用贪心策略找到局部最优以达到全局最优解。贪心算法并不总是适用,但在这类可以通过局部最优推导出全局最优的问题中表现出色。
摘要由CSDN通过智能技术生成

什么是贪心

贪心的本质是选择每一阶段的局部最优,从而达到全局最优。

这么说有点抽象,来举一个例子:

例如,有一堆钞票,你可以拿走十张,如果想达到最大的金额,你要怎么拿?

指定每次拿最大的,最终结果就是拿走最大数额的钱。

每次拿最大的就是局部最优,最后拿走最大数额的钱就是推出全局最优。

贪心的套路(什么时候用贪心)
很多同学做贪心的题目的时候,想不出来是贪心,想知道有没有什么套路可以一看就看出来是贪心。

说实话贪心算法并没有固定的套路。

所以唯一的难点就是如何通过局部最优,推出整体最优。

#找零问题
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

背包问题 [[vi元,wi千克],,,,,] 包只能装n千克

#分数背包/0-1背包


'''分数背包可以使用贪心算法解决,0-1背包不可以'''

goods=[[60,10],[120,30],[100,20]]      #每个商品的(价格,重量)

def fractional_backpack(goods,w):
    for i in range(len(goods)):         #给每个商品添加一个原始下标元素,在排序后,m按照原始下标进行加法
        goods[i].append(i)

    goods.sort(key=lambda x:x[0]/x[1],reverse=True)     #按照价格重量比排序
    m=[0 for _ in range(len(goods))]
    for (prise,weight,index) in goods:
        if w>=weight:
            m[index]=weight
            w-=weight

        else:
            m[index]=w
            break
    return m

print(fractional_backpack(goods,50))

拼接最大数字问题

有n个非负数字,拼接为最大数,如 12,45,9,41 拼接为9454112

from functools import cmp_to_key
def xy_cmp(x,y):
    if x+y<y+x:
        return 1
    elif x+y>y+x:
        return -1
    else:
        return 0



li=[32,94,128,1286,662,66]
def number_jion(li):
    li=list(map(str,li))
    li.sort(key=cmp_to_key(xy_cmp))
    return ''.join(li)

print(number_jion(li))

活动选择问题

n个活动,每个户活有个开始时间和结束时间,这些活动占用同一片场地,怎样安排,可以有最大的活动数

'''
每次都找最先结束的活动
'''

activatise=[(1,4),(3,5),(0,6),(5,7),(3,9),(5,9),(6,10),(8,11),(8,12),(12,16)]

#保证按结束时间排好序
activatise.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(activatise))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值