12.算法进阶之贪心算法(零钱找零、分数背包、数字拼接、活动场地)

1.零钱找零,使给钱的总张数是最少的,每种钱币的张数是无限的。

money = [100, 50, 20, 10, 5, 1]#有的零钱种类


def change_money(x, money):
    m = [0 for _ in range(len(money))]
    for i, val in enumerate (money):
        m[i] = x // val
        x = x % val
    return m,x
print(change_money(587.5,money))

2.分数背包,背包的总装是有限的,怎么拿使背包装的东西的价值最大.

1)改进前(使拿走的每个商品的比例列表与按单价排序后商品的列表是一一对应的)

goods = [(120, 30), (60, 10), (100, 20)]      #(物体总价,与其重量)
goods.sort(key=lambda x: x[0] / x[1], reverse=True)  # 排序
print(goods)


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


print(fractiomal_backpack(goods, 50))

2)改进后(使拿走的每个商品的比例列表与原始商品的列表是一一对应的)

goods = [(120, 30), (60, 10), (100, 20)]  #(物体总价,与其重量)



def fractiomal_backpack(goods, w):
    a={}
    b={}
    for ind,(val,wei) in enumerate(goods):        #将排序前数据下标和单价存储到字典中
        a[val/wei]=ind
    goods.sort(key=lambda x: x[0] / x[1], reverse=True)#排序

    m = [0 for _ in range(len(goods))]
    total_val = 0
    for i, (price, weight) in enumerate(goods):
        b[i]=price/weight                      #将排序后数据的下标和单价存储到字典中
        k=a.get(b.get(i))                      #将排序前的下标与m中存储数据相对应
        if w >= weight:
            m[k] = 1
            w = w - weight
            total_val += price
        else:
            m[k] = w / weight
            w = 0
            total_val += m[k] * price
            break
    return total_val, m


print(fractiomal_backpack(goods, 50))

3.数字拼接,使拼接出来的数字最大(判断a+b还是b+a大。例如7286和728,就不能只按字符串排序)

from functools import cmp_to_key  #要拼接的数字

li = [32, 94, 728, 7286, 6, 71]


def xy_cmp(x, y):              # cmp函数
    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))  # w为li加字符串
    li.sort(key=cmp_to_key(xy_cmp))  # 排序
    print(li)
    return ''.join(li)


print(number_join(li))

4.活动场地,使举办的活动最多(最先结束的活动一定在最优解中)

activities = [(1, 4), (3, 5), (5, 7), (0, 6), (3, 9), (5, 9), (6, 10), (8, 11),
 (8, 12), (2, 14), (12, 16)]                   #(每个活动开始时间,结束时间)
activities.sort(key=lambda x: x[1])    #占用时间排序


def activities_selection(activities):
    res = [activities[0]]                  #将最先结束的放在举办中
    for i in range(1, len(activities)):    #判断活动是否冲突
        if activities[i][0] >= res[-1][1]:
            res.append(activities[i])
    return res


print(activities_selection(activities))

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值