题意
你现在要洗L件衣服。你有n台洗衣机和m台烘干机。由于你的机器非常的小,因此你每次只能洗涤(烘干)一件衣服
。第i台洗衣机洗一件衣服需要wi分钟,第i台烘干机烘干一件衣服需要di分钟。请问把所有衣服洗干净并烘干,最
少需要多少时间?假设衣服在机器间转移不需要时间,并且洗完的衣服可以过一会再烘干
这题想了我很久啊QAQ
从昨天下午做到现在。。
一个不靠谱的题解
一开始,我想了一个O(nlog2n)的做法
就是洗衣机部分用优先队列搞
烘干机部分,二分答案,然后前面的在规定时间内,贪心使用时间大的,验证是否可行
这个过程可以用一个线段树来维护
然后似乎过不去
于是乎就需要一个O(nlogn)的做法
题解
首先,第一个环节,很好搞,由于都是一起进来的,所以我们贪心弄就可以了
问题就出在烘干机上面。
这个怎么弄呢?
我们先来思考一个问题,如果我们知道一个一起进来的最优方案,也就是说第一台机器用几次,第二台用几次。那么进来时间不一样,最优方案会不会变
明显地,是不会的。
这个的话,你仔细想一想就知道,如果进来时间不一样,对于机器的选择是没有影响的。
那么我们就考虑,我们对烘干机也做一次最优方案的选择,然后尝试合并起来。。
怎么合并呢?
大概思路就是最大的配最小的
那么这个答案的正确性呢?
我们考虑,第一个出来的用了i这个烘干机,那么对于后面的人来说,答案就从等
我们继续考虑,如果我们设c[i]为他从洗衣机里面出来的时间,f[j]那么j这个机器,之前所用的时间,能被烘干的时间就是min(c[i],f[j])
这代表什么意思呢?
也就是说,每一台机器,他结束工作的时间肯定是min(c[i],f[j])的最大值啊
于是,如果有i个人要用这个机器,现在轮到第j个人,那么他所可能造成的代价就是di?(i?j)+c[i],你在这些值里面取最大就是答案了。。
于是我们可以吧洗衣机争着做,烘干机倒着做就可以了
不知道我说清楚了没有,我感觉这是一个有一定思维难度的题吧。。如果有不懂的,可以留言
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long LL;
#define p pair<LL,LL>
const LL N=1000005;
LL l,n,m;
priority_queue <p,vector<p>,greater<p> > q;
LL c[N];
LL ans=0;
int main()
{scanf("%lld%lld%lld",&l,&n,&m);for (LL u=1;u<=n;u++){LL x;scanf("%lld",&x);q.push(make_pair(x,x));}for (LL u=1;u<=l;u++){LL x=q.top().first,y=q.top().second;q.pop();c[u]=x;q.push(make_pair(x+y,y));}while (!q.empty()) q.pop();for (LL u=1;u<=m;u++){LL x;scanf("%lld",&x);q.push(make_pair(x,x));}for (LL u=l;u>=1;u--){LL x=q.top().first,y=q.top().second;q.pop();ans=max(ans,c[u]+x);q.push(make_pair(x+y,y));}printf("%lld\n",ans);return 0;
}