/** 题目:hdu6000 Wash 巧妙地贪心 链接:https://vjudge.net/contest/173364#problem/B 转自:http://blog.csdn.net/overload1997/article/details/54730156 题意:L件衣服,N个洗衣机,M个烘干机,给出每个洗衣机洗一件衣服的时间和烘干机烘干一件衣服的时间,问需要的最少时间是多少。 思路:这是ccpcfinal的题目,明显是贪心但是很难想出来,首先洗衣服所需的最短时间应该很容易想出来了, 用优先队列弹出下一次先洗完的时间就好了,问题在于烘干,正解应该是倒过来想, 假设全部洗完洪完所需的最小时间是x,那么在x时刻,烘干机全部都已经工作完毕了, 即烘干机全部空闲,那么我们把时间倒过来看,烘干过程等于洗衣服过程,用同样的方法算出最快烘干时间, 然后要最快的时间故肯定是小的+大的,最后取最大值就是我们想要的x了,思路有点复杂,很难说清楚,还是上代码吧。 转自:http://blog.csdn.net/overload1997/article/details/54730156 */ #include<cstdio> #include<iostream> #include<vector> #include<cstring> #include<assert.h> #include<algorithm> #include<cmath> #include<queue> #define P pair<int,int> using namespace std; typedef long long LL; const int maxn = 1e6+200; LL time[maxn]; struct node { LL a, b; node(){} node(LL a,LL b):a(a),b(b){} bool operator < (const node&k)const{ return a+b>(k.a+k.b); } }top; int main() { int T, L, n, m, cas=1; cin>>T; while(T--) { scanf("%d%d%d",&L,&n,&m); priority_queue<node> q; LL t; for(int i = 1; i <= n; i++){ scanf("%lld",&t); q.push(node(0,t)); } for(int i = 1; i <= L; i++){ top = q.top(); q.pop(); time[i] = top.a+top.b; top.a+=top.b; q.push(top); } while(!q.empty()) q.pop(); for(int i = 1; i <= m; i++){ scanf("%lld",&t); q.push(node(0,t)); } LL ans = 0; for(int i = 1; i <= L; i++){ top = q.top(); q.pop(); ans = max(ans,top.a+top.b+time[L-i+1]); top.a += top.b; q.push(top); } printf("Case #%d: %lld ",cas++,ans); } return 0; }