题面:
思路:
一眼看得,这是贪心【雾】
实际上,我们要求的答案就是sigma(ci*(ti-i))(i=1~n),这其中sigma(ci*i)是确定的
那么我们就要最小化sigma(ci*ti)
所以在新的每一秒,就把这一秒开始可以起飞的飞机中,cost最大的那一个拿出来,让他起飞就可以了
证明:
设最大的为m,我们取得另一个为n
那么n*ti+m*(ti+1) >= n*(ti+1)+m*ti
所以取m最好
这个过程用堆实现,懒得手打了,就用了priority_queue
Code:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 inline int read(){ 8 int re=0,flag=1;char ch=getchar(); 9 while(ch>‘9‘||ch<‘0‘){ 10 if(ch==‘-‘) flag=-1; 11 ch=getchar(); 12 } 13 while(ch>=‘0‘&&ch<=‘9‘) re=(re<<1)+(re<<3)+ch-‘0‘,ch=getchar(); 14 return re*flag; 15 } 16 struct flight{ 17 int t,cost; 18 }a[300010]; 19 inline bool operator < (flight l,flight r){ 20 return l.cost<r.cost; 21 } 22 priority_queue<flight>q; 23 int n,k;long long tot=0; 24 int ans[300010]; 25 int main(){ 26 int i;flight tmp; 27 n=read();k=read(); 28 for(i=1;i<=n;i++) a[i].t=i,a[i].cost=read(); 29 for(i=1;i<=k;i++) q.push(a[i]); 30 for(i=k+1;i<=k+n;i++){ 31 if(i<=n) q.push(a[i]); 32 tmp=q.top();q.pop(); 33 ans[tmp.t]=i;tot+=(i-tmp.t)*1ll*tmp.cost; 34 } 35 printf("%lld\n",tot); 36 for(i=1;i<=n;i++) printf("%d ",ans[i]); 37 }