20181027T2易水决贪心+堆

Posted lstoi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了20181027T2易水决贪心+堆相关的知识,希望对你有一定的参考价值。

原题:loj6035

【错解】

全肝T1了没怎么想

【正解】

一眼贪心

先考虑(b_i=0)怎么做

可以模拟一个正常人的思维

开一个堆,记录每个任务需要的时间(包括等待),每次从中取出一个任务,表示现在这个东西空闲了,然后放入下一个任务

这样就可以处理出所有任务的时间,记为A

同样独立算出第二步的时间,记为B

那我们要求的就是将A、B重新排列使(max{A_i+B_i})最小

最大最小可以二分

感性理解就会发现,A升序,B降序使最小的

然后可以AC此题

#include <iostream>
#include <cstdio>
#include <utility>
#include <algorithm>
#include <queue>
#define MAXN 1000005
using namespace std;
typedef long long ll;
inline int read()
{
    int ans=0,f=1;
    char c=getchar();
    while (!isdigit(c))
    {
        if (c=='-') f=-1;
        c=getchar();
    }
    while (isdigit(c))
        ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    return f*ans;
}
typedef pair<ll,int> pi;//时间戳,等待时间 
priority_queue<pi,vector<pi>,greater<pi> > q;
int w[MAXN];
ll a[MAXN],b[MAXN];
void init(int n)
{
    for (int i=1;i<=n;i++)
    {
        w[i]=read();
        q.push(make_pair(w[i],w[i]));       
    }
}
void update(int l,ll a[])
{
    for (int i=1;i<=l;i++)
    {
        pi t=q.top();q.pop();
        a[i]=t.first;
        q.push(make_pair(t.first+t.second,t.second));
    }
    sort(a+1,a+l+1);
}
int main()
{
    int n,m,l;
    l=read(),n=read(),m=read();
    init(n);
    update(l,a);
    while (!q.empty()) q.pop();
    init(m);
    update(l,b);
    ll ans=0;
    for (int i=1;i<=l;i++)
        ans=max(ans,a[i]+b[l-i+1]);
    cout<<ans;
    return 0;
}

以上是关于20181027T2易水决贪心+堆的主要内容,如果未能解决你的问题,请参考以下文章

✨贪心+大根堆解决——>力扣502. IPO

bzoj4010: [HNOI2015]菜肴制作(拓扑排序+贪心+堆)

反悔贪心

可以反悔的贪心——贪心+堆维护

可以反悔的贪心——贪心+堆维护

易水之畔 自动刷冒险任务 刷金币 安卓模拟器 手机助手