贪心笔记

本文主要以例题讲解和贪心方法入手。

邻项交换

当我们确定操作顺序,并按照题意模拟即可得出答案,就要用邻项交换的办法来确定最优的操作顺序。

接水问题

对于一个排队顺序 T1Tn,答案显然等于:

i=1n(ni)×Tin

那么将其中的 T2,T3 拎出来,将他们交换位置,显然不会影响后面的 T 的计算,而:

(n1)×T2+(n2)×T3

变成了:

(n2)×T2+(n1)×T3

那么如果想让交换前的更优,显然需要满足:

(n1)×T2+(n2)×T3<(n2)×T2+(n1)×T3

即:

T2<T3

所以我们要按照 T 从小到大的顺序进行排序。这样就能取得最优值。


[NOIP2012 提高组] 国王游戏

同样,将排队顺序写出来后,即可按照题意模拟,将答案算出。

直接考虑第 i 个人的贡献:j=1i1ljri,第 i+1 个人的贡献显然是 j=1iljri+1,那么交换后,变成 li+1×j=1i1ljrij=1i1ljri+1,要想交换前更优,显然应该满足:

max{j=1i1ljri,j=1iljri+1}<max{li+1×j=1i1ljri,j=1i1ljri+1}

可以转化为比较:

j=1iljri+1<li+1×j=1i1ljri

即:

liri+1<li+1ri

即:

li×ri<li+1×ri+1

按照这个式子排序即可。


[yLOI2019] 梅深不见冬

先对问题进行简单的分析,如果我们将节点 k 的子儿子答案全部计算出来(记作 ansi,并设权值为 vi),并且将进入儿子的顺序确定下来,那么答案就是:

max{vk+v1+v2+...+vsiz(son),ans1,v1+ans2,vk+v1+v2+ans3...}

同样,我们取其中的两个 vk+j=1i1vj+ansivk+j=1ivj+ansi+1,交换后:vk+j=1i1vj+ansi+1vk+j=1i1vj+ansi+vi+1,那么我们只需要比较:

vk+j=1ivj+ansi+1<vk+j=1i1vj+ansi+vi+1

即可,就是满足:

viansi<vi+1ansi+1

处理所有节点时,按照这个排序即可。


魔法

一开始想了一个很离谱的贪心策略:对于目前所有可以做的任务,选择其中 b 最大的来做。但这样显然不对,比如:

2 10
9 -5
4 -2

就能将其卡掉,原因是先做 9 -5 再做 4 -2 可以做完,但是先做 4 -2 会导致 9 做不了。

从另外一个角度考虑:对于 b>0 的,先将其做了显然最优,接着考虑 b<0 的,考虑两个事件 t1,b1t2,b2,什么情况下使得先做 1 后做 2 可以,先做 2 后做 1 不行。

可以列出如下方程:

{T>t1T+b1>t2T>t2T+b2t1

有不等式相关性质不难得到:

t1+b1>t2+b2

所以按照 t+b 的值排序从大到小排序即可。

总结:“留后路”的前提是不会使得原来能做的事情变得不能做,所以凡是对于这种确定顺序模拟的题目,我们都可以使用邻项交换的方法进行分析。

posted @   2017BeiJiang  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
点击右上角即可分享
微信分享提示