思路:
使用堆计算。参考了https://zhuanlan.zhihu.com/p/78702574。
实现:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const ll INF=0x3f3f3f3f3f3f3f3f; 5 ll work(int lc,int rc,vector<ll>&c,vector<ll>&x){ 6 int n=c.size(); 7 vector<ll>pre(n,INF),suf(n,INF); 8 priority_queue<ll>q; 9 ll sum=0; 10 for(int i=0;i<n;i++){ 11 ll val=c[i]-x[i]; 12 if(lc==0){ 13 pre[i]=0; 14 continue; 15 } 16 if(q.size()<lc){ 17 q.push(val); 18 sum+=val; 19 } 20 else if(val<q.top()){ 21 q.push(val); 22 sum+=val; 23 sum-=q.top(); 24 q.pop(); 25 } 26 if(q.size()==lc){ 27 pre[i]=sum; 28 } 29 } 30 while(!q.empty())q.pop(); 31 sum=0; 32 for(int i=n-1;i>=0;i--){ 33 ll val=c[i]+x[i]; 34 if(rc==0){ 35 suf[i]=0; 36 continue; 37 } 38 if(q.size()<rc){ 39 q.push(val); 40 sum+=val; 41 } 42 else if(val<q.top()){ 43 q.push(val); 44 sum+=val; 45 sum-=q.top(); 46 q.pop(); 47 } 48 if(q.size()==rc){ 49 suf[i]=sum; 50 } 51 } 52 ll res=INF; 53 int begin=lc==0?0:1; 54 int end=rc==0?n:n-1; 55 for(int i=begin;i<end;i++){ 56 ll l=0,r=0; 57 ll tmp=c[i]; 58 if(lc>0){ 59 l=pre[i-1]+x[i]*lc; 60 } 61 if(rc>0){ 62 r=suf[i+1]-x[i]*rc; 63 } 64 res=min(res,tmp+l+r); 65 } 66 return res; 67 } 68 int main(){ 69 ios::sync_with_stdio(false); 70 int T;cin>>T; 71 for(int t=1;t<=T;t++){ 72 int k,n;cin>>k>>n; 73 vector<pair<ll,ll>>v; 74 vector<ll>x(n),c(n); 75 for(int i=0;i<n;i++){ 76 cin>>x[i]; 77 } 78 for(int i=0;i<n;i++){ 79 cin>>c[i]; 80 } 81 for(int i=0;i<n;i++){ 82 v.push_back({x[i],c[i]}); 83 } 84 sort(v.begin(),v.end()); 85 for(int i=0;i<n;i++){ 86 x[i]=v[i].first;c[i]=v[i].second; 87 } 88 89 ll res=work(k/2,k-k/2,c,x); 90 91 cout<<"Case #"<<t<<": "<<res<<endl; 92 } 93 return 0; 94 }