内容概要

  一、贪婪算法概念

  二、分数背包、01背包问题

  三、活动安排问题

  四、数字拼接问题

  五、找零问题  

 

1、贪婪算法概念

  贪婪算法是指,在对问题求解最优解时,总是做出当前开来最好的选择。也就是说不从整体最优上加以考虑,它做出的是在某种意义上的局部最优解。

  贪婪算法并不保证会得到最优解,但是在部分中,由贪婪算法得到的结果就是最优解。要判断一个问题是否能够使用贪婪算法解决

 

2、分数背包、01背包问题

 

  分数背包

    假设有一个小偷到商店偷东西,在他面前有价值600,共重1kg的商品A、价值1200,共重3kg的商品B、价值1000,共2kg的商品C,三种商品都能够被拆分携带。小偷只能拿走重5kg的物品。

    问:小偷要怎么拿才能带走价值最多的商品?

# 每次都拿走单位价值最高的商品
goods = [(600, 1), (1200, 3), (1000, 2)]
goods.sort(key=lambda x: x[0] / x[1], reverse=True)
print(goods)


def max_value(g, w):
    """
    :param g: good list
    :param w: max_w
    :return: tuple of change_method, total_value, remain_weight
    """
    m = [0 for _ in range(len(g))]
    total_v = 0
    for i, (prize, weight) in enumerate(g):
        if w >= weight:
            total_v += prize
            m[i] = weight
            w -= weight
        else:
            total_v += prize * w / weight
            m[i] = w
            w = 0
            break

    return m, total_v, w


print(max_value(goods, 5))

 

  01背包问题

    如果选择的商品不能分割,只能选择全部带走或者不选择

    这种情况下不适合使用贪婪算法求解最优解

 

3、活动安排问题

  假如有一个场地,同时只能开始一场活动,现在有若干个活动,它们分别从s时间开始,f时间结束(活动执行时间为[s,f)),现在求怎样安排活动能够使得一天内举办的活动次数最多

      i  1  2  3  4  5  6  7  8  9  10

        s  1  3  5  0  6  9  2  3  5   8

      f   4  5  7  2  8  10  4  5  6  10

activities = [(1, 4), (3, 5), (5, 7), (0, 2), (6, 8), (9, 10), (2, 4), (3, 5), (5, 6), (8, 10)]
activities.sort(key=lambda x: x[1])
print(activities)

# 贪婪地求活动结束时间最早的活动
def activity_max(a):
    m = [a[0]]
    a_num = 1
    for i in range(1, len(a)):
        if a[i][0] >= m[-1][1]:
            m.append(a[i])
            a_num += 1
    return m, a_num


print(activity_max(activities))

 

4、数字拼接问题

  假如有多个字符串数字123,423,88,92,23,现在要将他们拼接成最大的数928842323123,问如何完成

特别注意当存在128和1286,或是存在728或7286时

    如果只是单纯的比较大小,1286比128大,7286比728大,正常拼接后为1286128和7286728,前者是最大的拼接法,后者不是,最大的拼接数为7287286

    所以不使用a+b if a > b else b+a

    而是使用a+b if a+b > b+a else b+a

num_li = ['128', '1286', '88', '92', '29', '55']  # 想象成一个简单的冒泡排序


def number_join(a):
    length = len(a)
    for i in range(1, length):
        for j in range(length - i):
            if a[j] + a[j+1] < a[j+1] + a[j]:
                tmp = a[j]
                a[j] = a[j+1]
                a[j+1] = tmp
    result_num = ''
    for i in a:
        result_num += i

    return result_num


print(number_join(num_li))

 

5、找零问题

moneys = [100, 50, 20, 10, 5, 1]
moneys.sort(reverse=True)


def change(m_l, m):
    result = [0 for _ in range(len(m_l))]
    for i, v in enumerate(m_l):
        if not m:
            break
        result[i] = m // v
        m %= v
    return result, m


print(change(moneys, 277))

 

***待补充***