POJ 3270 Cow Sorting

题意:

一个序列变为升序,操作为交换两个元素,代价为两元素之和,求最小代价

题解:

看了黑书...

首先循环因子分解

一个循环完成的最小代价要么是循环中最小元素依次与其他交换,要么引入全局最小值来交换

$sum+min(mn*(len-2),mn+Min*(len+1))$

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=1e4+5,M=1e5+5;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
    return x*f;
}
int n,a[N],c[M],Min=M,m;
int f[N],ans;
bool vis[N];
int main(){
    //freopen("in","r",stdin);
    n=read();
    for(int i=1;i<=n;i++)
        a[i]=read(),c[a[i]]++,Min=min(Min,a[i]),m=max(m,a[i]);
    for(int i=1;i<=m;i++) c[i]+=c[i-1];
    for(int i=1;i<=n;i++) f[i]=c[a[i]];
    for(int i=1;i<=n;i++) if(!vis[i]){
        vis[i]=1;
        int u=f[i],sum=a[i],mn=a[i],len=1;
        while(u!=i) vis[u]=1,sum+=a[u],mn=min(mn,a[u]),len++,u=f[u];
        ans+=sum+min(mn*(len-2),mn+Min*(len+1));
    }
    printf("%d",ans);
}
View Code

相关文章:

  • 2021-06-30
  • 2021-08-24
  • 2021-11-18
  • 2021-04-19
  • 2021-12-01
  • 2021-04-12
  • 2021-07-11
  • 2021-04-01
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-01-14
  • 2022-02-15
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案