算法之贪心

什么是贪心

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

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

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

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

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

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

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

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

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

你可能感兴趣的:(数据结构与算法,算法,贪心算法,python)