最小成本排序

#include <iostream>
#include <algorithm>


using namespace std;
static const int MAX=1000;
static const int VMAX=10000;


int A[100],B[100],T[100];
bool V[100];


int solve(int N,int s)
{
    int ans=0;
    sort(B,B+N);
    for(int i=0;i<N;i++) T[B[i]]=i;//记录排序后的数组,其各个元素所对应的下标
    for(int i=0;i<N;i++)
    {
      if(V[i]) continue;
      int S=0;
      int cur=i;
      int m=INT_MAX;
      int tot=0;
      while(1)
      {
        V[cur]=true;
        tot++;
        int v=A[cur];
        S+=v;
        m=min(m,v);
        cur=T[v];
        if(V[cur]) break;
      }
      ans+=min(S+(tot-2)*m,m+S+(tot+1)*s);
    }
    return ans;
}


int main()
{
    int N,s=INT_MAX;
    cin>>N;


    for(int i=0;i<N;i++)
    {
       cin>>A[i];
       B[i]=A[i];
       V[i]=false;
       s=min(s,A[i]);
    }
    cout<<N<<endl;
    int ans=solve(N,s);
    cout<<ans<<endl;
    return 0;

}

总结:本问题一共设计了四个数组,其中B数组为A数组的拷贝,T数组可以理解为一个“映射”数组。所谓的映射是什么意思呢,就是建立元素及其下标关系的映射数组,这里学到一个技巧,就是通过数组来建立类似python中的“键值”对的元素映射关系。V数组用来记录某个元素是否被访问过,总之,这个题目给我的收获很大,以后要时常复习。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值