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

有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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值