#433 Div2 Problem C Planning (贪心 && 优先队列)
链接 : http://codeforces.com/contest/854/problem/C
题意 : 有 n 架飞机需要分别在 1~n 秒后起飞,允许起飞的时间是从 k 秒后开始,给出每一架飞机拖延一秒的花费c[1]~c[n],问你如何安排飞机的起飞次序能够使得花费最小?
分析 : 需要安排的时间段为 k+1 ~ k+n ,贪心的策略是按这个顺序每一次选择花费最小 并且 不早于飞机规定的起飞时间的飞机区起飞必然能得到最优方案,因此我们可以构造一个优先队列每一次将待选飞机存放进去按照花费从小到大排序,但是不能一下子把所有的飞机存放进去,因为假如对于当前的某一个时间点 T ,如果有一个飞机的规定起飞时间比这个时间晚那么肯定不能安排到这个时间 T 上。所以我们是对于当此时的飞机规定起飞时间 > k 然后一个个放进去的。
#include<bits/stdc++.h> using namespace std; const int maxn = 3e5 + 10; class plane { public: int id; int cost; bool operator < (const plane & rhs) const{ return this->cost < rhs.cost; }; }; plane arr[maxn]; int ans[maxn]; int main(void) { int n, k; scanf("%d %d", &n, &k); priority_queue<plane> pq; while(!pq.empty()) pq.pop(); for(int i=1; i<=n; i++){ scanf("%d", &arr[i].cost); arr[i].id = i; } for(int i=1; i<=k; i++) pq.push(arr[i]); long long Cost = 0; int cnt = k+1; while(!pq.empty()){ if(cnt <= n) pq.push(arr[cnt]); plane now = pq.top(); pq.pop(); ans[now.id] = cnt; Cost += (long long)(cnt - now.id) * (long long)now.cost; cnt++; } cout<<Cost<<endl; for(int i=1; i<=n; i++) printf("%d ", ans[i]); return 0; }