反悔贪心 -- 反悔堆

反悔贪心,顾名思义,就是可以反悔的贪心算法。

 

反悔贪心有两种实现方式:一种是利用堆实现,成为反悔堆;另一种是通过差值构造来构造出反悔自动机,让任何一种贪心策略都可以得到最优解。

 

 

本题我们可以先对lastday进行排序,之后遍历列表若能加入堆,直接加入;若不能加入,则看一看堆顶元素和当前元素的关系,若堆顶元素更大一些则舍弃堆顶并

进行反悔策略,更新答案。

复制代码
class Solution:
    def scheduleCourse(self, courses: List[List[int]]) -> int:
        cur = 0
        hp = []
        courses.sort(key = lambda x: x[1])
        for dur, lst in courses:
            if cur + dur <= lst:
                heappush(hp, -dur)
                cur += dur
            elif hp and -hp[0] > dur:
                cur -= -hp[0] - dur
                heappop(hp)
                heappush(hp, -dur)

        return len(hp)
                
复制代码

 

 

 本题,我们利用反悔策略来进行考虑。

先按profit从大到小排序,建立哈希表存储当前种类的个数。

利用lst数组来存储每次枚举到新元素时要替换谁。

复制代码
class Solution:
    def findMaximumElegance(self, items: List[List[int]], k: int) -> int:
        items.sort(key = lambda x: -x[0])
        st, lst = set(), []
        cur, tot, ans = 0, 0, 0

        for i, (profit, catagory) in enumerate(items):
            if i < k:
                tot += profit
                if catagory not in st:
                    st.add(catagory)
                else:
                    lst.append(profit)
            elif lst and catagory not in st:
                st.add(catagory)
                tot -= lst.pop()
                tot += profit
            ans = max(ans, tot + len(st) ** 2)
        
        return ans
复制代码

 

 

 我们按照deadline进行排序,然后从前到后进行枚举。

本题中每个 任务时间相同,所以,heap.size()就是当前消耗了多少时间。

复制代码
import heapq
n = int(input())
arr = []
for i in range(n):
    arr.append(list(map(int, input().split())))

arr.sort(key=lambda x: x[0])
hp = []
tot = 0

for ddl, prof in arr:
    if ddl > len(hp):
        tot += prof
        heapq.heappush(hp, prof)
    elif hp and prof > hp[0]:
        tot -= hp[0]
        heapq.heappop(hp)
        tot += prof
        heapq.heappush(hp, prof)

print(tot)
复制代码

 

 反悔贪心--差值构造

本题中最优解的M(money)in和Mout 有一组等式关系:Mout - Min = (Mout - Mi) + (Mi - Min) Mi 表示任意一天股票价格。

我们进行股票活动时,能卖出,就卖出,并加入heap中。若卖出的时机不是最优解,则会在后面出堆进行反悔。

 

复制代码
import heapq

n = int(input())
arr = list(map(int, input().split()))

ans = 0
hp = []

for it in arr:
    heapq.heappush(hp, it)
    if hp and hp[0] < it:
        ans += it - hp[0]
        heapq.heappop(hp)
        heapq.heappush(hp, it)

print(ans)
复制代码

 

posted @   深渊之巅  阅读(192)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)
点击右上角即可分享
微信分享提示