ZZK说这是傻逼题
但是我觉得好难啊
显然,要使最终归为有序,必定构成若干个置换群
对于每个置换群有两种方案:
- 找群里最小的点,交换一圈
- 群里最小点与群外最小点交换,交换一圈,再换回来
然后就没有然后了
示例程序:
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=50005,INF=0x3f3f3f3f;
int n,a[maxn],id[maxn],MIN=INF;
LL ans;
bool vis[maxn];
bool mycomp(const int&i,const int&j){
return a[i]<a[j];
}
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]),id[i]=i,MIN=min(MIN,a[i]);
sort(id+1,id+1+n,mycomp);
for (int i=1;i<=n;i++)
if (!vis[i]){
LL tot=0,Min=INF,sum=0;//printf("%d ",i);
for (int j=i;!vis[j];j=id[j]){//printf("%d ",j);
vis[j]=1;Min=min(Min,(LL)a[j]);
sum+=a[j];tot++;
}//putchar('\n');
ans+=min((tot-2)*Min+sum,MIN+Min+tot*MIN+sum);
}
printf("%lld",ans);
return 0;
}