CF853A 计划

题目描述:

有n架飞机,第 i 架飞机原本计划在第 i 分钟起飞,可是由于某种原因整个机场前 k 分钟是不能起飞的,并且每分钟只能起飞一架飞机,然后告诉你每架飞机每延误一分钟会造成的损失,问你如何安排飞机的起飞时间才能将损失降到最少(飞机不能提前起飞)

输入格式:

第一行包含两个整数n和k(1≤k≤n≤1e5),其中n是航班数,k是航班未离开的当天开始的分钟数。

第二行包含n个整数c1,c2,...,cn(1≤ci≤1e7),这里ci是延迟第i个航班一分钟的费用。

输出格式:

第一行必须包含延迟航班的最低可能总成本。

第二行必须包含n个不同的整数t1,t2,...,tn(k +1≤ti≤k+ n),这里ti是第i个航班必须离开的分钟。 如果有多个最佳时间表,请打印其中任何一个

输入样例:

5 2
4 2 1 10 2

输出样例:

20
3 6 7 4 5

解题思路:

设di为第i架飞机的实际起飞时间(1 <= i <= n)
ci为一架飞机延误一分钟的费用
总成本 = ∑ (di - i) * ci
易证当di尽量小的时候,当前飞机的费用尽量小

但存在着前k分钟不能起飞,一分钟只能起飞一架飞机的限制,所以我们要采取贪心策略,优先满足消耗大的飞机,从小的时间往后安排

#include <bits/stdc++.h>
#define maxn (300010)

typedef long long ll;

struct data /* 结构体 */
{
    ll cost;
    int id;
    bool friend operator<(const data &x, const data &y) { return x.cost < y.cost; }
};

std::priority_queue<data >q;

int t[maxn];
ll cost[maxn];

int main()
{
    int n, k;
    ll ans = 0;
    scanf("%d%d", &n, &k);
    for (int i = 1; i <= n; i++)
        scanf("%lld", &cost[i]), ans -= cost[i] * i;
    while (!q.empty())
        q.pop();
    for (int i = 1; i <= k; i++)
        q.push((data){cost[i], i});
    int time = k + 1;
    while (!q.empty())
    {
        if (time <= n)
            q.push((data){cost[time], time});
        data a = q.top();
        q.pop();
        t[a.id] = time;
        ans += time * a.cost;
        time++;
    }
    printf("%lld\n", ans);
    for (int i = 1; i <= n; i++)
        printf("%d%c", t[i], i == n ? '\n' : ' ');
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/wyctstf/p/11243497.html