惊了,省选考枚举。
显然,学生等待的代价只和最后一科成绩公布的时间有关。
而后\(b_i\leq1e5\)。
因此就能够枚举最后一科结束的时间\(T\)。
算出让最后一科在t时间出成绩的最小代价。
取个\(min\)就好了。
怎么求让最后一科在T时间出成绩的最小代价?
当\(B<=A\)时直接把全部公布时间大于\(T\)的科目,提早。
不然消耗\(A\)的代价让公布时间小于\(T\)的科目日后推,不能再推了再消耗\(B\)的代价提早。
丑陋的代码ios
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define int long long const int N=101000; int A,B,C,n,m,a[N],b[N],book[N],bok[N],w[N],cnt,tmp,num,tot,ret,ans=1e18; int read(){ int sum=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();} return sum*f; } signed main(){ A=read(),B=read(),C=read(); n=read();m=read(); for(int i=1;i<=n;i++)a[i]=read(),book[a[i]]++; for(int i=1;i<=m;i++)b[i]=read(),w[b[i]]+=b[i],bok[b[i]]++; sort(a+1,a+1+n); sort(b+1,b+1+m); if(b[m]<a[1]){printf("0");return 0;} for(int i=1;i<=m;i++){ if(b[i]<a[1])tot+=b[i],num++; else ret+=b[i]; } cnt=0;tmp=0; for(int i=a[1];i<=b[m];i++){ if(B<=A)ans=min(ans,tmp+(ret-(m-num)*i)*B); else{ if(num*i-tot>=ret-(m-num)*i)ans=min(ans,tmp+(ret-(m-num)*i)*A); else ans=min(ans,tmp+(num*i-tot)*A+(ret-(m-num)*i-(num*i-tot))*B); } cnt+=book[i]; tmp+=cnt*C; if(tmp>=ans)break; num+=bok[i]; tot+=w[i]; ret-=w[i]; } printf("%lld",ans); return 0; }