Codeforces-854C - Planning - 贪心(利用优先队列实现)

使用优先队列解决Codeforces-854C - Planning问题
这篇博客介绍了如何解决Codeforces上的一个编程问题——Planning,涉及航班调度和贪心算法。作者通过创建一个新的起飞顺序,以最小化因航班延误造成的总成本。文章详细解释了题意、贪心策略、代码实现,以及如何使用优先队列(最大堆)优化解决方案。

原题目链接

    http://codeforces.com/contest/854/problem/C

题目

Helen works in Metropolis airport. She is responsible for creating a departure schedule. There are n flights that must depart today, the i-th of them is planned to depart at the i-th minute of the day.

Metropolis airport is the main transport hub of Metropolia, so it is difficult to keep the schedule intact. This is exactly the case today: because of technical issues, no flights were able to depart during the first k minutes of the day, so now the new departure schedule must be created.

All n scheduled flights must now depart at different minutes between (k + 1)-th and (k + n)-th, inclusive. However, it's not mandatory for the flights to depart in the same order they were initially scheduled to do so — their order in the new schedule can be different. There is only one restriction: no flight is allowed to depart earlier than it was supposed to depart in the initial schedule.

Helen knows that each minute of delay of the i-th flight costs airport ci burles. Help her find the order for flights to depart in the new schedule that minimizes the total cost for the airport.

Input

The first line contains two integers n and k (1 ≤ k ≤ n ≤ 300 000), here n is the number of flights, and k is the number of minutes in the beginning of the day that the flights did not depart.

The second line contains n integers c1, c2, ..., cn (1 ≤ ci ≤ 107), here ci is the cost of delaying the i-th flight for one minute.

Output

The first line must contain the minimum possible total cost of delaying the flights.

The second line must contain n different integers t1, t2, ..., tn (k + 1 ≤ ti ≤ k + n), here ti is the minute when the i-th flight must depart. If there are several optimal schedules, print any of them.

Example

Input

5 2
4 2 1 10 2

Output 

20
3 6 7 4 5 

Note

Let us consider sample test. If Helen just moves all flights 2 minutes later preserving the order, the total cost of delaying the flights would be (3 - 1)·4 + (4 - 2)·2 + (5 - 3)·1 + (6 - 4)·10 + (7 - 5)·2 = 38 burles.

However, the better schedule is shown in the sample answer, its cost is (3 - 1)·4 + (6 - 2)·2 + (7 - 3)·1 + (4 - 4)·10 + (5 - 5)·2 = 20 burles. 

题意

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

题目分析

首先,很容易想到这个题目利用贪心策略,所以我们首先要确定如何来进行贪心。每架飞机每延误一分钟都造成损失,那么我们只要保证每一分钟的损失都是最小的,那么结果一定是最优的。(正确性显然)

所以我们对当前的某一分钟进行分析,都有那些飞机可能在这一分钟产生损失呢?那些晚点的飞机和当前这一分钟正点的飞机都有可能产生损失。所以我们从这些飞机中选择出来一个每分钟损失最大的飞机,让它在这一分钟起飞,那么这一分钟这一架飞机就不会产生损失(正点的和晚点的都是),并且之后也不会在产生损失。其他的飞机(包括晚点的和正点的)都会在这一分钟产生损失。这样我们每一分钟的方案就确定下来了。

那么如何来实现呢?我们可以借助于STL中的优先队列(最大堆)来实现这个功能。先晚点的都压入到优先队列中,然后每分钟压入当前正点的飞机,并弹出这一分钟应该起飞的飞机。当没有正点的飞机时,逐个弹出队列中的元素即可。

代码

#include<cstdio>
#include<queue>
#include<algorithm>

using namespace std;

struct node{
	long long c;
	int time;
	int ntime;
	bool operator < (const node & a) const
    {
        return c<a.c;
    }
};
priority_queue<node>pq;
node a[300010];

bool cmp(node a,node b)
{
	return a.time<b.time; 
}

int main()
{
	int n,k;
	scanf("%d%d",&n,&k);
	int i=1;
	for(;i<=k;i++)
	{
		node temp;
		scanf("%lld",&temp.c);
		temp.time=i;
		pq.push(temp);
	}
	int cnt=0;
	for(;i<=n;i++)
	{
		node temp;
		scanf("%lld",&temp.c);
		temp.time=i;
		pq.push(temp);
		temp=pq.top();
		pq.pop();
		temp.ntime=i;
		a[cnt++]=temp;
	}
	for(int j=i;j<=i+k;j++)
	{
		node temp=pq.top();
		pq.pop();
		temp.ntime=j;
		a[cnt++]=temp;
	}
	sort(a,a+n,cmp);
	long long ans=0;
	for(int i=0;i<n;i++)
		ans+=a[i].c*(a[i].ntime-a[i].time);
	printf("%lld\n%d",ans,a[0].ntime);
	for(int i=1;i<n;i++)
		printf(" %d",a[i].ntime);
	putchar('\n');
	return 0;
}

 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值