1. 程式人生 > >【20181027T2】易水決【貪心+堆】

【20181027T2】易水決【貪心+堆】

怎麽 init 下一個 turn ron prior first define int

原題: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】易水決【貪心+堆】