我们登上的并非我们|

vanueber

园龄:2年6个月粉丝:0关注:2

贪心tricks总结

贪心题一般没有什么技巧,多做题积累经验。

对于结论或策略,大胆猜想,小心求证,注意使用数据结构优化/结合其他算法。

一般类贪心

主要是证明贪心的正确性。

H. Fight Against Monsters

先用二分求出每个怪需要打的次数。

问题转化为
1

一个排列的答案是

i=1nijnaj

考虑邻项交换 i,i+1,答案的变化就为

bijinaj+bi+1jinaj(bi+1jinaj+bijinaj)=bi+1aibiai+1

如果交换更优,应满足

bi+1ai<biai+1

biai>bi+1ai+1

按照属性升序排序即可。

打怪兽2

对于 biai 的肯定先打,按照 ai 排序。

对于 bi<ai 的,考虑邻项交换。

设现在还剩血量 t,面对怪兽 (ai,bi),(ai+1,bi+1),若不交换更优,应满足

tai0tai+biai+10tai+1<0  tai+1+bi+1ai<0

bi<ai

tai+1>0

只能有

tai+1+bi+1ai<0

进一步

ai+ai+1bit<ai+1+aibi+1

bi>bi+1

按照 b 降序排序即可。

反悔贪心

P2949 [USACO09OPEN] Work Scheduling G

题目大意:给个任务有一个截止时间,每个时间安排一个任务,求最大利润。

朴素贪心想法:按照截止时间排序,优先做利润大的。

问题在于如果后面出现了利润更大的,但前面的已经被安排满了,就会导致贪心策略错误,故这种情况就要反悔操作。

使用一个优先队列维护一个做过的决策集合,如果当前任务还能做,直接加入集合。否则,从之前的决策中取利润最小的替换掉。

这个操作等价于没有做之前的利润小的任务,直接做了利润更大的任务,从局部最优满足了全局最优。

sort(a+1,a+1+n);
for(int i=1;i<=n;++i)
{
    if(a[i].d<=Q.size())
    {
        if(Q.top()>a[i].p) continue;
        else
        {
            int x=Q.top();
            Q.pop();
            ans+=a[i].p-x;
            Q.push(a[i].p);
        }
    }
    else
    {
        ans+=a[i].p;
        Q.push(a[i].p);
    }
}

P4053 [JSOI2007] 建筑抢修

题目大意:每个任务有所需时间和截止时间,求最多能安排多少任务。

朴素贪心:按照截止时间排序,扫一遍判断是否能做。

此时就会有无法做的任务,我们会直接舍弃,给前面一个任务很多的时间,贪心错误,考虑反悔。

用一个大根堆维护决策集合,具体维护其时间。如果当前时间能够做这个任务,就直接做。否则,一定有一个任务是不能做的,只能尽可能地压缩当前时间,以保证后面能安排更多的任务。于是考虑从大根堆中取出耗费时间最多的决策去除,消去其贡献。

注意一定要先贪心再反悔。


贪心证明:

假设我们确定了要选 S 中的所有任务,通过邻项交换推导策略。

记之前已经用的时间为 t,即 k=1i1ak=t

对于相邻的 i,j,交换前更优,即满足交换后就没法完成第二个任务了,有

t+aidi,t+ai+ajdj

交换后有

t+ajdj,t+aj+ai>di

整理一下,有

di<dj

故是按照截止时间排序。


int now=0,cnt=0;
for(int i=1;i<=n;++i)
{
    now+=a[i].t1;
    Q.push(a[i].t1);
    if(now<=a[i].t2)
    {
        ++cnt;
    }
    else
    {
        int x=Q.top();
        Q.pop();
        now-=x;
    }
}

然后就可以通过转化,将这个问题建模为其他问题:

Zabuton

将每个人抽象成任务,拥有任务所需时间和截止时间,那么添加的砖就是任务所需时间,最初的砖不能超过 H,等价于最后的砖不能超过 H+P,可以转化为截止时间。

for(int i=1,p,h;i<=n;++i)
{
    h=read(),p=read();
    a[i].t1=p,a[i].t2=p+h;
}

本文作者:vanueber

本文链接:https://www.cnblogs.com/vanueber/p/18710140

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   vanueber  阅读(2)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起