贪心算法

贪心算法

最大购买

问题:有N元钱, 有三种商品, 价格分别为150元, 200元, 350元, 在最大购买下最少能剩下多少钱.
思路:350=150+200, 排除此商品, 全购买150元的商品, 如果还有余钱, 把150元的商品换成200元.
python code

N = 580
cnt = N//150
sum = N%150

while sum>=50 and cnt>0:
    sum -= 50
    cnt -= 1

print(sum)

最少支付

问题: 有n个坑, 体积为v, 有m堆沙子, 体积为x, 用体积为x的沙子可以填满深度<=x的坑, 但是要支付x元, 如何支付最少的钱?(不能组合沙子填坑.)
思路: 对坑和沙子的序列进行排序, 依次尝试是否能填满.
* python code*

P = [7, 3, 9, 5, 1]
S = [5, 4, 7, 8, 2, 3, 9]

P.sort()
S.sort()

sum, begin = 0, 0

for i in range(len(P)):
    for j in range(begin, len(S)):
        if S[j] >= P[i]:
            sum += S[j]
            begin = j+1
            break
    else:
        print('no')
        break
else:
    print(sum)

最多不相交区间

问题: 有N个区间(a, b), 尽量选择多个区间, 他们之间没有公共点.
思路: 按b对区间进行排序, 不管是a1>a2还是a1小于a2, 选择(a1,b1)更划算, 选择(a1, b1)后, 余下的区间又是一个新区间组, 递归此步骤.
python code

class Area:
    def __init__(self, a, b):
        self.a, self.b = a, b

A = [
    Area(2, 5), Area(1, 4), Area(2, 3), Area(5, 6),
    Area(1, 2), Area(3, 5), Area(3, 6), Area(1, 3)
]

A.sort(key=lambda x: x.b)

max_b = 0

for item in A:
    if item.a >= max_b:
        print(item.a, item.b)
        max_b = item.b

Huffman树

问题: 给定一组序列, 2个数的和合成1个父节点, 生成一颗权值最小的树, 第N层权值为N.
思路:每次选择序列中最小的2个数构成左节点和右节点, 再把它们的父节点的值放进序列, 递归此步骤.
python code
构造节点核心算法

from queue import PriorityQueue
A = [4, 2, 1, 5, 9, 8, 6]
Q = PriorityQueue()

for item in A:
    Q.put(item)

while Q.qsize() > 1:
    min1, min2 = Q.get(), Q.get()
    Q.put(min1+min2)
    print(min1, min2)

print(Q.get())

构造树 先序遍历输出结果

from queue import PriorityQueue

class Tree:
    def __init__(self, lc, rc, data):
        self.lc, self.rc, self.data = lc, rc, data

    def __lt__(self, other):
        return True if other.data > self.data else False

def show(node):
    if node:
        print(node.data)
        show(node.lc)
        show(node.rc)

A = [4, 2, 1, 5, 9, 8, 6]
Q = PriorityQueue()

for item in A:
    Q.put(Tree(None, None, item))

while Q.qsize() > 1:
    lc, rc = Q.get(), Q.get()
    parent = Tree(lc, rc, lc.data+rc.data)
    Q.put(parent)

show(Q.get())
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值