您的位置:首页 > 其它

【51Nod1125】交换机器的最小代价

2017-08-03 13:18 260 查看
有N台机器重量各不相等,现在要求把这些机器按照重量排序,重量从左到右依次递增。移动机器只能做交换操作,但交换机器要花费一定的费用,费用的大小就是交换机器重量的和。例如:3 2 1,交换1 3后为递增排序,总的交换代价为4。给出N台机器的重量,求将所有机器变为有序的最小代价。(机器的重量均为正整数)

Input

第1行:1个数N,表示机器及房间的数量。(2 <= N <= 50000)

第2 - N + 1行:每行1个数,表示机器的重量Wi。(1 <= Wi <= 10^9)

Output

输出最小代价。

Input示例

3

3

2

1

Output示例

4

题解

贪心,可以发现交换的机器组成一个一个环,互不干扰,所以有两种决策。

第一种策略:用这些机器(假如为x个)中重量最小的依此和需要交换的机器交换。这种情况下,其它所有机器交换一次,最小重量的机器交换x次。

第二种策略:用所有机器中重量最小的依此和这些机器交换。再把重量最小的换回到第一个位置。这种情况下,重量最小的那个交换x+2(换出去换回来各一次)次,其他的交换一次.但有一个特殊的,最后把最小的那个交换回来的要多交换一次。也就是两次。我们自然会选取重量最小的那个作为特殊机器。

代码

#include<bits/stdc++.h>
#define N 500005
#define ll long long
#define inf 1000000009
#define mod 1000000007
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
struct node{int v,id;}a[50005];
int n,Min=inf;ll ans;
bool vis[50005];
bool cmp(node a,node b){return a.v<b.v;}
int main()
{
n=read();
for (int i=1;i<=n;i++)
{
a[i].v=read();
a[i].id=i;
Min=min(Min,a[i].v);
}
sort(a+1,a+n+1,cmp);
for (int i=1;i<=n;i++)
{
if (vis[i]) continue;
int p=i,mini=inf,sz=0;ll sum=0;
while (!vis[p])
{
vis[p]=1;
mini=min(mini,a[p].v);
sum+=(ll)a[p].v;
sz++;
p=a[p].id;
}
ans+=min(sum+(ll)(sz-2)*(ll)mini,(ll)Min*(sz+1)+sum+mini);
}
printf("%lld",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: