Planning CodeForces - 854C

Helen works in Metropolis airport. She is responsible for creating a departure schedule. There aren 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 firstk 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 airportci 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 andk (1 ≤ k ≤ n ≤ 300 000), heren 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), hereci is the cost of delaying thei-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 integerst1, t2, ..., tn (k + 1 ≤ ti ≤ k + n), hereti is the minute when thei-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个飞机原本顺序起飞(从第一分钟到第n分钟)。但是现在,给定k,前k分钟飞机不能起飞,让你重新排列起飞顺序,使损失最小(每架飞机晚点一分钟的损失已经给出)。

因为如果不晚点就不会赔钱,而晚点的每架飞机都在赔钱。所以我们每次都把要晚点的飞机中损失最大的起飞。比如第一次我们就把前k+1架中损失最大的起飞,所以样例飞机的起飞顺序为1,4,2,5,3,而对应的时间为3,4,5,6,7。将他们按飞机顺序输出就是3,5,7,4,6(和样例不一样,但也是对的,题目并没有要求)。

思路就是上面这样的,我将给出两种算法。

第一种是同学写的。用了set。先将最后的时间全部存进去(k+1到k+n)。然后碰到对应的就取出来,直到取完。因为set默认从小到大的,所以每次取的时候用upper_bound( )

将符合要求的最小时间取出来就行。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<cstdlib>
using namespace std;
struct node {
    int v,t;                                   //v 为晚点每分钟的损失,t为原本起飞时间
};
node c[3000005];                               //用来储存原本的飞机序列
int a[3000005];                                //用来储存最后的起飞时间序列                                                          bool cmp(node a,node b){                       
    if (a.v==b.v)
        return a.t<b.t;
    return a.v>b.v;
}
set<int>s;
int main(){
    int n,k;
    scanf("%d%d",&n,&k);
    for (int i=1;i<=n;i++){
        scanf("%d",&c[i].v);
        c[i].t=i;
        s.insert(k+i);
    }
    sort(c+1,c+1+n,cmp);
    long long sum=0;
    for (int i=1;i<=n;i++){
        int p=*s.upper_bound(c[i].t-1);                       //找到set中刚好时间后最近的
        sum+=(long long)(p-c[i].t)*c[i].v;
        a[c[i].t]=p;
        s.erase(p);
    }
    printf("%lld\n",sum);
    for (int i=1;i<=n;i++)
        printf("%d ",a[i]);
    system("pause");
    return 0;
}

第二种用优先队列写的。因为只要确保在晚点中选亏损最多的就行,所以按照亏损情况排序。先将前k个压入队列,然后压入一个出一个就行。确保每次出来的都是队列里面亏损最大的那个。

#include<iostream>
#include<queue>
using namespace std;
struct node {                 
	int cost,id;
	friend bool operator < (node a,node b) {              //按照亏损大小,大的在前面
		return a.cost<b.cost;
	}
} a[300005];
priority_queue<node> q;
int b[300005];
int main() {
	int n,k;
	cin>>n>>k;
	for(int i=1; i<=n; i++) {
		cin>>a[i].cost;
		a[i].id=i;
	}
	for(int i=1; i<=k; i++)                     //先将前k个压入队列
		q.push(a[i]);
	int m=k+1;
	long long num=0;
	while(!q.empty()) {
		if(m<=n)                            //全部入队了就不压了
			q.push(a[m]);
		node x=q.top() ;
		q.pop();
		b[x.id]=m;
		num+=(long long)(m-x.id)*x.cost;          //这里一定要注意long long (w了几次)
		m++;
	}
	cout<<num<<endl;
	for(int i=1; i<=n; i++)
		cout<<b[i]<<" ";
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章