【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;
}
posted @ 2018-10-27 17:08  lst_mengbier  阅读(163)  评论(0编辑  收藏  举报