链接:https://ac.nowcoder.com/acm/contest/554/I
来源:牛客网
坑坑作为一个ACMer,经常要对一组数字进行排序,在排序过程中,将两个数字交换位置的花销是这两个数字的和,慢慢的他想实现一种最低花销的排序方式,你们能帮助他吗?
输入描述:
输入包含多组测试数据。 每组测试输入包含一组数字包含的整数个数n以及n个整数mi(1<=n<1000,0<=mi<=10000)给定的整数互不重复。
输出描述:
对于每组测试数据,输出一个整数,给定整数按升序排序时所需花销的最小值。
示例1
输入
复制
4 3 1 5 4
输出
复制
13
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=1e5+5;
int a[maxn],b[maxn];
bool vis[maxn];
int main() {
int n;
while(cin>>n) {
memset(vis,false,sizeof(vis));
map<int,int>m;
int ksmin=inf;
for(int i=0;i<n;i++) {
cin>>a[i];
ksmin=min(ksmin,a[i]);
}
memcpy(b,a,sizeof(int)*n);
sort(b,b+n);
for(int i=0; i<n; i++) m[a[i]]=b[i];
ll ans=0;
for(int i=0; i<n; i++) {
if(!vis[a[i]]) {
int p=a[i],sum=0,minn=a[i],len=0;
while(!vis[p]) {
sum+=p;
len++;
minn=min(minn,p);
vis[p]=true;
p=m[p];
}
ans+=min(sum-minn+(len-1)*minn,sum+minn+(len+1)*ksmin);
}
}
cout<<ans<<endl;
}
return 0;
}