驚了,省選考枚舉。
顯然,學生等待的代價只和最後一科成績公佈的時間有關。
而後\(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; }