题解:P11908 [NHSPC 2023] G. 博物館
题目大意
需要将 \(n\) 个元素中前 \(k\) 大的挪到前 \(k\) 个位置,求最小的总代价。
解题思路
想到了用结构体来解此题,储存每一个元素的大小与编号。然后按照元素从大到小进行排序,得到一个新的顺序,此时前 \(k\) 个就是需要放在前 \(k\) 位的。
在此之后,为防止无效挪动(比如向后挪动),可以再将前 \(k\) 个元素再按编号从小到大排序,这样既可以保证前 \(k\) 个元素是所有元素中前 \(k\) 大的,也可以保证挪动次数最小。
由此,我们只需要对输入的 \(c_i\) 进行两次排序即可。
代码
#include <bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
int n,k,ans;
struct node{
int id,v;//id存储编号,v存储价值
}c[114514];
bool cmp1(node a,node b){
if(a.v==b.v)return a.id<b.id;//价值相等时,确保编号小的在前
return a.v>=b.v;//保证排序后价值是从高到低
}
bool cmp2(node a,node b){
return a.id<b.id;//保证排序后编号是从低到高
}
int main(){
ios;
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>c[i].v;
c[i].id=i;
}
sort(c+1,c+1+n,cmp1);//按所有作品价值,从高到低排序
sort(c+1,c+1+k,cmp2);//按前k个作品的编号,从低到高排序
for(int i=1;i<=k;i++){
ans+=c[i].id-i;//将第id个作品挪到第i个的代价
}
cout<<ans;
return 0;
}
完结撒花~
本文来自博客园,作者:Circle_Table,转载请注明原文链接:https://www.cnblogs.com/Circle-Table/articles/19177400

浙公网安备 33010602011771号