zoukankan      html  css  js  c++  java
  • BZOJ 1697: [Usaco2007 Feb]Cow Sorting牛排序(置换+贪心)

    题面

    Description

    农夫JOHN准备把他的 N(1 <= N <= 10,000)头牛排队以便于行动。因为脾气大的牛有可能会捣乱,JOHN想把牛按脾气的大小排序。每一头牛的脾气都是一个在1到100,000之间的整数并且没有两头牛的脾气值相同。在排序过程中,JOHN 可以交换任意两头牛的位置。因为脾气大的牛不好移动,JOHN需要X+Y秒来交换脾气值为X和Y的两头牛。 请帮JOHN计算把所有牛排好序的最短时间。
    Input

    第1行: 一个数, N。

    第2~N+1行: 每行一个数,第i+1行是第i头牛的脾气值。
    Output

    第1行: 一个数,把所有牛排好序的最短时间。
    Sample Input
    3

    2

    3

    1

    输入解释:

    队列里有三头牛,脾气分别为 2,3, 1。

    Sample Output
    7

    输出解释:

    2 3 1 : 初始序列

    2 1 3 : 交换脾气为3和1的牛(时间=1+3=4).

    1 2 3 : 交换脾气为1和2的牛(时间=2+1=3).

    解题思路

      比较有意思的一道题。首先目标序列向原序列对应连边一定会形成若干个环,所以答案其实就是每个环造成的贡献。贪心的想,一个环的贡献首先可以是这个环内最小的元素倒着换一圈,还可以是环内最小的元素先跟全局最小元素换一次,然后让全局最小元素换一圈,然后再换回来(这两种需要画图体会),所以我们每个环在这两种里面取个(min)即可。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    
    using namespace std;
    const int MAXN = 10005;
    typedef long long LL;
    
    inline int rd(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
    	while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    	return f?x:-x;	
    }
    
    int n,f[MAXN],col,Min,val[MAXN];
    LL ans;
    bool vis[MAXN];
    
    struct Data{
    	int id,a;	
    	friend bool operator<(const Data A,const Data B) {
    		return A.a<B.a;	
    	}
    }data[MAXN];
    
    inline int min(int x,int y){
    	return x<y?x:y;	
    }
    
    int main(){
    	n=rd();int now,cnt,x;
    	for(int i=1;i<=n;i++) data[i].id=i,data[i].a=rd();sort(data+1,data+1+n);
    	for(int i=1;i<=n;i++)
    		f[data[i].id]=i,val[data[i].id]=data[i].a;
    	for(int i=1;i<=n;i++){
    		if(vis[i] || f[i]==i) continue;
    		Min=1e9;now=i;cnt=0;
    		while(!vis[now]) {
    			Min=min(Min,val[now]);vis[now]=1;
    			ans+=val[now];now=f[now];cnt++;
    		}
    		ans+=min((cnt-2)*Min,(Min+(cnt+1)*data[1].a));
    	}
    	printf("%lld
    ",ans);
    	return 0;	
    }
    
  • 相关阅读:
    基于centOS7→nginx安装
    基于centOS7→tomcat安装配置
    chmod、acl权限
    解决终端SSH连接服务器一段时间不操作之后卡死的问题
    客户端加域失败,提示“找不到网络名”解决的方案
    将博客搬至CSDN
    Qt on android 蓝牙开发(控制小车)
    qt程序运行时的错误error:undefined reference to `_imp___ZN10QTcpSocketD1Ev'
    QT 实现在QLabel上画图
    linux文件访问权限(像rw-r--rw-是什么意思)
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/10058843.html
Copyright © 2011-2022 走看看