标签:efi char blog 位置 n+1 div lld 高度 交换机
题意:N个高度不一的机器,排成一列,为了把他们排成高度递增的一列,每次可以交换两个机器,代价为两个机器的和
题解:
贪心+置换
1、用每个置换内部的最小值交换置换长度减一次,其他点交换一次
2、引入外部的最小点,交换它与内部最小点的位置,交换置换长度+2次后再把内部最小点换回来,其他点交换一次
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
const int N = 50010;
int Mi;
bool vis[N];
struct Node {
int v,p;
bool operator < (const Node &x) const {
return v<x.v;
}
}a[N];
int gi() {
int x=0,o=1; char ch=getchar();
while(ch!=‘-‘ && (ch<‘0‘ || ch>‘9‘)) ch=getchar();
if(ch==‘-‘) o=-1,ch=getchar();
while(ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
return o*x;
}
ll solve(int i) {
int mi=a[i].v,j=a[i].p,cnt=0;
ll ret=a[i].v;
vis[i]=1;
while(j!=i) {
vis[j]=1;
ret+=a[j].v;
mi=min(mi,a[j].v);
j=a[j].p;
cnt++;
}
return ret+min(1ll*(cnt-1)*mi,1ll*(cnt+2)*Mi+mi);
}
int main() {
int n=gi(); ll ans=0;
for(int i=1; i<=n; i++) {
a[i].v=gi();
a[i].p=i;
}
sort(a+1,a+n+1);
Mi=a[1].v;
for(int i=1; i<=n; i++) {
if(!vis[i]) ans+=solve(i);
}
printf("%lld", ans);
return 0;
}
标签:efi char blog 位置 n+1 div lld 高度 交换机
原文地址:http://www.cnblogs.com/HLXZZ/p/7535750.html