bzoj 5088: HDU 6000 Wash

题意

你现在要洗L件衣服。你有n台洗衣机和m台烘干机。由于你的机器非常的小,因此你每次只能洗涤(烘干)一件衣服
。第i台洗衣机洗一件衣服需要wi分钟,第i台烘干机烘干一件衣服需要di分钟。请问把所有衣服洗干净并烘干,最
少需要多少时间?假设衣服在机器间转移不需要时间,并且洗完的衣服可以过一会再烘干

这题想了我很久啊QAQ
从昨天下午做到现在。。

一个不靠谱的题解

一开始,我想了一个 O(nlog2n) 的做法
就是洗衣机部分用优先队列搞
烘干机部分,二分答案,然后前面的在规定时间内,贪心使用时间大的,验证是否可行
这个过程可以用一个线段树来维护
然后似乎过不去
于是乎就需要一个 O(nlogn) 的做法

题解

首先,第一个环节,很好搞,由于都是一起进来的,所以我们贪心弄就可以了
问题就出在烘干机上面。
这个怎么弄呢?
我们先来思考一个问题,如果我们知道一个一起进来的最优方案,也就是说第一台机器用几次,第二台用几次。那么进来时间不一样,最优方案会不会变
明显地,是不会的。
这个的话,你仔细想一想就知道,如果进来时间不一样,对于机器的选择是没有影响的。
那么我们就考虑,我们对烘干机也做一次最优方案的选择,然后尝试合并起来。。
怎么合并呢?
大概思路就是最大的配最小的
那么这个答案的正确性呢?
我们考虑,第一个出来的用了 i 这个烘干机,那么对于后面的人来说,答案就从等di的时间,要加上他,对吧,那么时间效率就是后面还有多少个人要用这个机器
我们继续考虑,如果我们设 c[i] 为他从洗衣机里面出来的时间, f[j] 那么j这个机器,之前所用的时间,能被烘干的时间就是 min(c[i],f[j])
这代表什么意思呢?
也就是说,每一台机器,他结束工作的时间肯定是 min(c[i],f[j]) 的最大值啊
于是,如果有i个人要用这个机器,现在轮到第j个人,那么他所可能造成的代价就是 di(ij)+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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值