B - Planning 早训 贪心

时间:2019-08-23
本文章向大家介绍B - Planning 早训 贪心,主要包括B - Planning 早训 贪心使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

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\n", res);
    for (int j = 1; j <= n; j++) printf("%d ", ans[j]);
    return 0;
}

原文地址:https://www.cnblogs.com/EchoZQN/p/11398747.html