上午做了他们省选的模拟赛
感觉好累啊,没啥状态
这题属于签到题,解法好想也好打,没心情拍,不过最后也算是签到成功了吧
题目和学生可以分开来讨论,对两个数组分别排序
从小到大爆枚最晚出分的时间
分别算出等待的时间和调度的花费更新答案
注意B特别大的时候B一定不会作为最优解,直接特判掉不要算出来,那个值特别大会大于264
时间复杂度取决于排序的复杂度,使用基数排序可以做到O(N),但是这里用了更好写的快速排序,时间复杂度为O(N∗log2N)
#include <bits/stdc++.h>
#define INF (1LL<<62)
#define N 200050
using namespace std;
typedef long long LL;
int t[N],b[N],n,m,tp,x,y;
LL A,B,C,sum;
inline int rd() {int r;scanf("%d",&r);return r;}
void init() {
A = rd(), B = rd(), C = rd();
n = rd(), m = rd();
for (int _=1;_<=n;_++) t[_] = rd(); sort(t+1,t+n+1);
for (int _=1;_<=m;_++) b[_] = rd(); sort(b+1,b+m+1);
}
LL calc(LL _, LL x, LL fr) {
LL dmd = sum-fr-_*(m-x), res = min(_*x-fr, dmd);
if (B>N) return res>=dmd ? dmd*A : INF;
return min(1LL*dmd*B, 1LL*res*A+1LL*(dmd-res)*B);
}
void solve() {
tp = t[n]; x = 1; y = 1;
for (int _=1;_<=m;_++) sum += b[_];
LL S=0LL, fr=0LL, ans=INF;
for (int _=1;_<=tp;_++) {
while (x<=n && t[x] < _) S += t[x++];
while (y<=m && b[y] < _) fr += b[y++];
LL cur = calc(_, y-1, fr);
ans = min(ans, 1LL * C * ( 1LL*(x-1)*_-S ) + cur);
}
cout << ans << endl;
}
int main() {
init();
solve();
return 0;
}