B - Planning
这个题目我知道要贪心,也知道怎么贪,但是写不出来,感觉自己好菜。
这个题目要用优先队列维护。
题目大意是飞机延误,不同的飞机每次延误一分钟,它的代价不同,然后问,怎么安排才能使飞机延误的代价最小,
唯一的限制就是飞机只能往后延误,不能提前。
然后看了网上的题解,首先我们把 1~ k 时候起飞的飞机直接放入优先队列,队列按照代价从大到小排序,
然后再考虑k+1~n的飞机,每次放入一架飞机,我们就可以求出一架在这个时刻最优的飞机。
为什么这么贪心是对的呢,首先如果前面的飞机每一分钟的代价很大,那这个位置肯定是最优的,
如果后面的飞机代价很大,因为后面的每一架飞机都可以就选择它原来起飞的时刻,所以肯定比这个时刻优,而且后面的飞机不能提前起飞。
意思就是这个时刻只能飞比这个时间小的所有的飞机。
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <queue> #include <vector> #include <iostream> #include <string> #define inf 0x3f3f3f3f #define inf64 0x3f3f3f3f3f3f3f3f using namespace std; const int maxn = 6e5 + 10; typedef long long ll; struct node { int mon, id; node(int mon = 0, int id = 0) :mon(mon), id(id){} bool operator<(const node& a)const { return a.mon > mon; } }ex[maxn]; int ans[maxn]; priority_queue<node>que; int main() { int n, k; scanf("%d%d", &n, &k); for(int i=1;i<=k;i++) { int x; scanf("%d", &x); que.push(node(x, i)); } ll res = 0; for(int i=k+1;i<=n;i++) { int x; scanf("%d", &x); que.push(node(x, i)); int a = que.top().id; int b = que.top().mon; res += abs(i - a)*1ll*b; ans[a] = i; que.pop(); } int i = n + 1; while(!que.empty()) { int a = que.top().id, b = que.top().mon; res += abs(i - a)*1ll*b; ans[a] = i; que.pop(); i++; } printf("%lld ", res); for (int j = 1; j <= n; j++) printf("%d ", ans[j]); return 0; }