poj3270--Cow Sorting(置换群)

题目链接:点击打开链接

题目大意:给出你n个数,要求把这n个数排列成有序的(由小到大),每次可以交换两个数,花费是这两个数的和,现在求最小的花费

置换群的入门

求出每一个轮换的圈,对于每一个轮换中,只有在自身内交换就能完成有序,而不需要和其它轮换交叉。

一个轮换的最小值temp,轮换中有num个数,轮换的总和是sum,整个序列的最小值min1

让一个轮换花费最少有两种可能

1、轮换自身交换,轮换的最小值和其他值交换num-1次,那么花费是sum-temp+(num-1)*temp

2、用全局的最小值和轮换的最小值交换,然后执行轮换自身交换,然后再用全局最小值把轮换的最小值交换回来

sum-temp+(num-1)*min1+2*(min1+temp)

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define LL __int64
#define INF 0x3f3f3f3f
LL a[10010] , b[10010] , id[100010] ;
int vis[10010] ;
int main() {
    int n , i , j ;
    LL ans = 0 , min1 , num , sum , temp ;
    memset(vis,0,sizeof(vis)) ;
    scanf("%d", &n) ;
    for(i = 1 , min1 = INF ; i <= n ; i++) {
        scanf("%d", &a[i]) ;
        b[i] = a[i] ;
        id[ a[i] ] = i ;
        min1 = min(min1,a[i]) ;
    }
    sort(b+1,b+n+1) ;
    for(i = 1 ; i <= n ; i++) {
        if( vis[i] || a[i] == b[i] ) continue ;
        j = i ;
        sum = num = 0 ;
        temp = INF ;
        while( !vis[ id[ b[j] ] ] ) {
            j = id[ b[j] ] ;
            sum += a[j] ;
            num++ ;
            vis[ j ] = 1 ;
            temp = min(temp,a[j]) ;
        }
        ans += min( sum-temp+(num-1)*temp , sum-temp+(num-1)*min1+2*(min1+temp) ) ;
    }
    printf("%I64d\n", ans) ;
    return 0 ;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 11:08:07

poj3270--Cow Sorting(置换群)的相关文章

POJ3270 cow sorting 【polya】

题目描述: 给你一个数字序列(每个数字唯一),每次你可以交换任意两个数字,代价为这两个数字的和,问最少用多少代价能把这个序列按升序排列好. 题目的具体做法是参考刘汝佳的<算法艺术与信息学奥赛>大概思路是:以后再用别种方法解, 1.找出初始状态和目标状态.明显,目标状态就是排序后的状态. 2.画出置换群,在里面找循环.例如,数字是8 4 5 3 2 7 明显,                                   目标状态是2 3 4 5 7 8,能写为两个循环:(8 2 7)(4

poj 3270 Cow Sorting 置换群 简单题

假设初始状态为 a:2 3 1 5 4 6 则目标状态为 b:1 2 3 4 5 6且下标为初始状态中的3 1 2 4 5 6(a[3],a[1]...) 将置换群写成循环的形式 (2,3,1),(5,4),6就不用移动了. 移动方式2种 1:选循环内最小的数和其他len-1个数交换 2:选整个序列最小的数和循环内最小的数交换,转到1,再换回来. #include<cstdio> #include<queue> #include<algorithm> #include&

Cow Sorting(置换群)

Cow Sorting Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6664   Accepted: 2602 Description Farmer John's N (1 ≤ N ≤ 10,000) cows are lined up to be milked in the evening. Each cow has a unique "grumpiness" level in the range 1...

poj3270 Cow Sorting

置换群的第二题,一开始总是tle,后来一思考,置换根本不是这个情况,置换是一种排列,就用了几个数组将输入的数进行操作,最后A了,对置换有一些了解了. #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 10000+10; int n,least; int a[maxn],b[1000010],s[maxn],tmp[1000010]; v

poj 3270 Cow Sorting(初涉置换群)

http://poj.org/problem?id=3270 大致题意:给出n个整数,要将它们转化成递增序列,每交换其中两个数的代价是这两个数之和.问排序成功后的最小代价. 该题考察的是置换群知识.在黑书p247上有详细的讲解.总结下置换群,方便复习. 群:给定一个集合G={a,b,c...}和集合G上的二元运算 ·,如果满足封闭性,结合律,存在单位元和逆元,则成集合G在运算'·'之下是一个群. 置换:n个元素1,2,....,n之间的置换可表示为  1     2     3     ...

POJ 3270 Cow Sorting(置换群)

题目链接 题意 : N头牛,每个牛的坏脾气都有一个值,每个值都不相同,把这个值按照从小到大排序,如果两个值交换,那么会花掉这两个值之和的时间,让你花最少的时间将每个值从小到大排好序,求最小的总时间. 思路 : 这个在黑书上有写,就是置换群,248页有写.写的挺详细的.每个状态都可以分为若干个循环的乘积.对于任意循环 i ,设其长度为ki,则至少需要交换ki-1次,即每次让一个元素到达目标位置,而当第ki-1个元素到达目标以后显然第ki个也已经到达目标.第一个方法是让循环中最小的元素t参加所有的交

【POJ 3270】Cow Sorting(置换群排序)

Cow Sorting(置换群排序) Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 6909 Accepted: 2716 Description Farmer John's N (1 ≤ N ≤ 10,000) cows are lined up to be milked in the evening. Each cow has a unique "grumpiness" level in the range 1

poj 3270 Cow Sorting

Cow Sorting 题意:有N头牛,每头牛都有不同的暴躁值ai,现在要将所有的牛按照暴躁值从小到大排序,每次交换两个元素(任意交换)时,花费就是两头牛的暴躁值之和:问排序的最小花费为多少? 数据:(1 ≤ N ≤ 10,000) (1 <= ai <= 100,000); 思路:很明显的贪心:(下面讲的循环是置换群里的循环) 策略:我们从没在最终位置且值最小的牛看起,如果每次都是将当前考虑的牛直接与它最终的位置的牛交换,那么这样递推下去,将形成的就是一个循环(一定有牛的最终位置为考虑的起始

POJ 3270 Cow Sorting(置换环)

Cow Sorting Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6393   Accepted: 2476 Description Farmer John's N (1 ≤ N ≤ 10,000) cows are lined up to be milked in the evening. Each cow has a unique "grumpiness" level in the range 1...

hdu 2838 Cow Sorting 树状数组

hdu2838 ------希望30号驾校科目一顺利考完,4月即将过去说好的30篇博客也没完成, 真是忙起来就会烦躁什么都不想做,勿忘心安.... <Cow Sorting> 这题本来兴高采烈的想用java做一遍,结果做出来之后无限超内存,真是啊,做题的时候java这种东西还是轻易不要动了.还有感觉要把数字都要离散化的,结果后台数据不需要离散化. 题意:给一个n代表n个牛,然后再给n个数我觉得是n以内的数(包括n).虽然体面上没说.然后只能相邻两个数字交换位置,会让牛产生怒气值,值为互相移动的