1. 程式人生 > 其它 >#6035. 「雅禮集訓 2017 Day4」洗衣服

#6035. 「雅禮集訓 2017 Day4」洗衣服

題目

前言

這個貪心有點妙,考試的時候沒有想出來,一看題解恍然大悟。

分析

首先對於洗衣服,顯而易見我們可以用堆來處理,可以得出每件衣服洗完的時間 \(t_i\),其中 \(t_i\) 表示的是第 \(i\) 早的衣服洗完的時間,那對與烘衣服呢?正著做好像不太好做,因為每件衣服的洗完時間都不同,不能(至少我不會)貪心。那我們可以假定一個洗完烘完衣服的時間,從那個時間點往前做,就是倒著做,然後又可以用堆來做了,得到 \(s_i\) ,含義與 \(t_i\) 類似,即烘衣服花的時間,那怎麼匹配呢,顯然是最大的和最小的,次大的和次小的 \(\dots\)以此類推。如果不是這樣子,顯然會使其中一個值變大,使得答案可能會增大,顯然不會是最優的。

\(code\)

#include<bits/stdc++.h>
#define N 100005
#define M 1000005
using namespace std;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
int n,na,nb;
int a[N],b[N];
long long ans,t[M],s[M];
struct node{
	long long ed;
	int use;
	bool operator < (const node &A) const {return A.ed<ed;}
};
priority_queue<node> q1,q2;
signed main(){
//	freopen("laundry.in","r",stdin);
//	freopen("laundry.out","w",stdout);
	n=read(),na=read(),nb=read();
	for(int i=1;i<=na;++i) a[i]=read(),q1.push((node){a[i],a[i]});
	for(int i=1;i<=nb;++i) b[i]=read(),q2.push((node){b[i],b[i]});
	for(int i=1;i<=n;++i){
		t[i]=q1.top().ed,q1.push((node){t[i]+q1.top().use,q1.top().use});
		q1.pop();
		s[i]=q2.top().ed,q2.push((node){s[i]+q2.top().use,q2.top().use});
		q2.pop();
	}
	for(int i=1;i<=n;++i) ans=max(ans,t[i]+s[n-i+1]);
	printf("%lld\n",ans);
//	fclose(stdin);
//	fclose(stdout);
	return 0;
}