C.Planning
题目传送门
题意&分析:
机场有n架飞机,第 i 架起飞时间是 i ,现在机场前 k 单位时间不可以有飞机起飞,所以得推迟航班。第 i 架航班每延误 1 单位时间就要花费机场 ci 的费用,现在求最小的赔偿费用。
这是一个优先队列+贪心的题目,对于前 k 架次的航班全部入队,因为他们肯定延误了,然后将剩下的航班依次加入队列(前面放走一架,后面就有一架飞机要延误,所以要加入队列中),然后取队首元素(按照花费较大的原则)。。。
代码如下:
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define TEST cout<<"stop here"<<endl
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
struct node {
ll id,cost;
bool operator <(const node a)const{
return cost < a.cost;//最大值优先
}
}a[300005];
ll odr[300005];
ll n,k;
priority_queue<node> que;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
while(cin>>n>>k){
memset(odr,0,sizeof(odr));
for(ll i=1;i<=n;i++){
cin>>a[i].cost;
a[i].id = i;
}
ll d = min(n,k);
for(ll i=1;i<=d;i++){
que.push(a[i]);
}
ll ans = 0;
for(ll i=k+1;i<=n+k;i++){
if(i<=n){
que.push(a[i]);
}
node tmp = que.top();
que.pop();
ans += (i - tmp.id) * tmp.cost;
odr[tmp.id] = i;
}
cout<< ans <<endl;
for(int i=1;i<=n;i++){
cout<< odr[i] << ((i!=n) ? " ":"\n");
}
}
return 0;
}