题意:
- 将负责课程
的部分教师调到课程 ,调整后课程 的公布时间推迟一天,课程 的公布时间提前一天,每次操作产生 不愉快度; - 增加部分老师负责课程
,这将使课程 的公布时间提前一天,每次操作产生 不愉快度。
你可以多次执行操作,
数据范围与约定:
| Case # | ||
|---|---|---|
| 1,2 | ||
| 3,4 | ||
| 5,6,7,8 | ||
| 9,10,11,12 | ||
| 13,14 | ||
| 15,16,17,18,19,20 |
解析:我们可以发现,学生的不愉快度只与最后出成绩的时间有关,且出成绩的时间越晚,学生的不愉快度单调递增,但老师的不愉快度是单调递减的。两个加起来是一个单谷函数,所以可以三分。我们三分最后出成绩的时间
#include<cstdio>
#include<algorithm>
using namespace std;
long long n,m,t[101010],b[101010];
long long A,B,C,ans;
long long count(long long x)//贪心统计操作产生的不愉快度
{
long long u=0;
long long v=0;
for(int i=1;i<=m;i++)
if(x>b[i])
u+=x-b[i];
else
v+=b[i]-x;
if(A<B)
return min(u,v)*A+(v-min(u,v))*B;
else
return v*B;
}
int main()
{
int i,j;
scanf("%lld%lld%lld%lld%lld",&A,&B,&C,&n,&m);
for(i=1;i<=n;i++)
scanf("%lld",&t[i]);
for(i=1;i<=m;i++)
scanf("%lld",&b[i]);
sort(t+1,t+n+1);
sort(b+1,b+m+1);
if(C>=1e16)
ans=count(t[1]);
else
{
ans=1e16;
long long l=1,r=200005;
while(r-l>5)
{
long long mid=l+(r-l)/3;
long long mmid=r-(r-l)/3;
long long f1=count(mid);
long long f2=count(mmid);
for(i=1;i<=n;i++)
if(t[i]<mid)
f1+=C*(mid-t[i]);//加上等待产生的不愉快度
for(i=1;i<=n;i++)
if(t[i]<mmid)
f2+=C*(mmid-t[i]);
if(f1<=f2)
r=mmid;
else
l=mid;
}
for(i=l;i<=r;i++)
{
long long x=count(i);
for(j=1;j<=n;j++)
if(t[j]<i)
x+=C*(i-t[j]);
ans=min(ans,x);//在三分出的(l,r)的范围内求最小值
}
}
printf("%lld",ans);
return 0;
}

