贪心,从值最小的开始交换,把该位置的值换过来,但是如果值最小的已经在正确位置上了,那么就有两种方式,一种是从值次小的开始交换,第二种是把次小的值跟最小值交换,然后从最小值交换,贪心的时候取两者最优即可。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1e4+9;
int a[maxn],b[maxn],f[maxn*10];
int main()
{
// freopen("in.txt","r",stdin);
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=a[i];
f[a[i]]=i;
}
sort(b+1,b+1+n);
int st=1,ret=0;
long long ans=0;
while(st<=n)
{
if(f[b[st]]==st)
{
if((b[st]-b[1])*ret>(b[st]+b[1])*2)
ans-=(b[st]-b[1])*ret-(b[st]+b[1])*2;
st++;
ret=0;
}
else
{
swap(a[f[b[st]]],a[f[b[f[b[st]]]]]);
ans+=b[st]+b[f[b[st]]];
swap(f[b[st]],f[b[f[b[st]]]]);
ret++;
}
}
cout<<ans<<endl;
}
return 0;
}