Codeforces 854 - C Planning

题意:对于给定的N个飞机降落时刻。现在需要延迟K分钟。需要重新安排飞机降落时刻。唯一的限制是新的降落时刻表中,每架飞机的降落时刻不能早于原来的时刻。同时,每架飞机有一个延迟费用,每于原来的起降时刻有一分钟的差值则需要支付一定的延误费用Ci

思路:对于每架飞机的延误费用Ci,和新时刻表起飞的时间Ti,总花费有这样的公式:

SUM=i=1nCi(Tii)

转化后可得:

SUM=i=1nCiTii=1nCii

可知,后部分等式,为定值,要使得结果最小,需要使得前半部分值最小。

设对于i,j两架飞机消耗的总花费

Ci(Tii)+Cj(Tjj)

如果交换i,j的新起降时间可得:

Ci(Tji)+Cj(Tij)

设交换后总花费大于原费用可得:

Ci(Tii)+Cj(Tjj)<Ci(Tji)+Cj(Tij)

化简可得:
Ci<Cj

可得贪心策略:
在满足要求的情况下(Ti>i),取当前合法解中Ci最大的。

#include <bits/stdc++.h>

using namespace std;

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

struct node
{
    ll p, c;
    node(ll a = 0, ll b = 0)
    {
        p = a;
        c = b;
    }
};

struct cmp
{
    bool operator()(node x, node y)
    {
        if (x.c != y.c)return x.c > y.c;
        return x.p < y.p;
    }
};

set<node, cmp>s;
int a[300000 + 50];
int main()
{
    ll k;
    int n;
    scanf("%d%I64d", &n, &k);
    ll ans = 0;
    for (int i = 1; i <= n; i++)
    {
        ll c;
        scanf("%I64d", &c);
        s.insert(node(i, c));
        if (i >= k + 1)
        {
            a[s.begin()->p] = i;
            ans += s.begin()->c*(i - s.begin()->p);
            s.erase(s.begin());
        }
    }
    for (int i = 1; i <= k; i++)
    {
        a[s.begin()->p] = i + n;
        ans += s.begin()->c*(i + n - s.begin()->p);
        s.erase(s.begin());
    }
    printf("%I64d\n", ans);
    //printf("%I64d\n", ans);
    for (int i = 1; i <= n; i++)
    {
        if (i != 1)printf(" ");
        printf("%d", a[i]);
    }
    printf("\n");
    //sp;
}
©️2020 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值