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]<<" ";
}


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