题目描述:
有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;
}