<题目链接>
题目大意:
表示有n架飞机本需要在[1,n]时间内起飞,一分钟只能飞一架.但是现在[1,k]时间内并不能起飞,只能在[k+1,k+n]内起飞.ci序号为i的飞机起飞延误一分钟的costi.每个飞机起飞时间不能比原定时间早,请安排一个起飞顺序,求最小的cost和。
解题分析:
贪心策略证明:转载于>>>
设序号为i的飞机起飞时间为di,则cost=∑(di-i)*cj=∑di*cj-∑j*cj。显然后一项为常数,而{di-k}为[1,n]的一个排列, 所以只要使ci越大的i尽可能早起飞即可使得cost最小。
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 8 typedef long long ll; 9 #define N int(3e5+10) 10 ll ans[N]; 11 struct Node{ 12 ll loc,val; 13 Node(ll a1,ll a2):loc(a1),val(a2){} 14 bool operator < (const Node & tmp)const{ 15 return val<tmp.val; 16 } 17 }; 18 int main(){ 19 ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); 20 priority_queue<Node>q; 21 int n,k;cin>>n>>k; 22 ll sum=0; 23 for(ll i=1;i<=n+k;i++){ 24 if(i<=n){ 25 ll cal;cin>>cal; 26 q.push(Node(i,cal)); 27 } 28 if(i>k){ 29 Node now=q.top();q.pop(); 30 sum+=(i-now.loc)*now.val; //起飞时间早的飞机与多的花费优先相乘 31 ans[now.loc]=i; 32 } 33 } 34 cout<<sum<<endl; 35 for(int i=1;i<=n;i++) 36 i==n?printf("%lld ",ans[i]):printf("%lld ",ans[i]); 37 }
2019-02-01