题目链接

题意 : N头牛,每个牛的坏脾气都有一个值,每个值都不相同,把这个值按照从小到大排序,如果两个值交换,那么会花掉这两个值之和的时间,让你花最少的时间将每个值从小到大排好序,求最小的总时间。

思路 : 这个在黑书上有写,就是置换群,248页有写。写的挺详细的。每个状态都可以分为若干个循环的乘积。对于任意循环 i ,设其长度为ki,则至少需要交换ki-1次,即每次让一个元素到达目标位置,而当第ki-1个元素到达目标以后显然第ki个也已经到达目标。第一个方法是让循环中最小的元素t参加所有的交换,其他元素值参加一次,总花费为sum+(k-2)t。sum为循环中所有元素的和。

但是这个并不是最优的。

例如初始状态是2 3 1,目标状态是1 2 3,形成的下标数组是3 1 2。

1 2 3

3 1 2

这个置换对应的循环是(1 3 2),只有一个循环节,交换的代价是1+3=4 1+2=3总代价是7

很明显我们是用(1 3 2)这个循环里的最小的数去和其他的数交换,这样能使最后的代价最小,并且一个循环的交换次数是k-1次,k 是这个循环包含的数的个数。

但是这种考虑的方法不一定是最优的,样例中只有一个循环节,若有多个循环节,我们可以用别的循环里的比这个循环里的所有的数小的数来和这个循环里的数来交换,付出的代价不一定比先前那种思路大,所以第二方面我们要考虑把所有数中最小的数与各个循环里最小的数交换,然后与前面那种思路付出的代价比较,取较小的那个。

公式就是ans=sum+∑(从1到n)min{(cnt-2)*t,t+(cnt+1)*m}

 //
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm> using namespace std ; struct node
{
int position ;
int level ;
}a[];
bool cmp(node c,node d)
{
return c.level < d.level;
}
int N,minn = ;
int ans ;
bool vis[] ; void solve()
{
memset(vis,false ,sizeof(vis)) ;
ans = ;
int cnt , t , sum ,pos ;
for(int i = ; i < N ; i++)
{
if(!vis[i])
{
vis[i] = true ;
cnt = ;
t = sum = a[i].level ;
pos = a[i].position ;
while(pos != i)
{
sum += a[pos].level ;
vis[pos] = true ;
t = min(t,a[pos].level) ;
pos = a[pos].position ;
cnt ++ ;
}
ans += sum + min((cnt-)*t,t+(cnt+)*minn) ;
}
}
printf("%d\n",ans) ;
}
int main()
{
scanf("%d",&N) ;
for(int i = ; i < N ; i++)
{
a[i].position = i ;
scanf("%d",&a[i].level) ;
minn = min(minn,a[i].level) ;
}
sort(a,a+N,cmp) ;
solve() ;
return ;
}

POJ 3270 Cow Sorting(置换群)的更多相关文章

  1. POJ 3270 Cow Sorting(置换群)

    题目链接 很早之前就看过这题,思路题把,确实挺难想的,黑书248页有讲解. #include <cstdio> #include <cstring> #include < ...

  2. poj 3270 Cow Sorting

    思路:仔细读题,看到FARMER是两两交换牛的顺序进行排序的话,应该就往置换上靠拢,而这个题果然是置换的应用(有的解题报告上说是置换群,其实这只是单个置换,不用让它构成群).我们来将这些无序的牛抽象成 ...

  3. poj 3270 Cow Sorting (置换入门)

    题意:给你一个无序数列,让你两两交换将其排成一个非递减的序列,每次交换的花费交换的两个数之和,问你最小的花费 思路:首先了解一下什么是置换,置换即定义S = {1,...,n}到其自身的一个双射函数f ...

  4. Cow Sorting(置换群)

    Cow Sorting Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6664   Accepted: 2602 Descr ...

  5. 【POJ】3270.Cow Sorting

    题解 用到一点群论的知识! 我们发现把操作写成一个置换后,一定是单个置换圈的内进行操作,把置换圈进行扩大的操作不优 我们有两个办法,一个是用全局最小的换进来,代替这个圈里最小的值,交换操作完成后再换出 ...

  6. TOJ 1690 Cow Sorting (置换群)

    Description Farmer John's N (1 ≤ N ≤ 10,000) cows are lined up to be milked in the evening. Each cow ...

  7. poj 3270(置换群+贪心)

    Cow Sorting Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6993   Accepted: 2754 Descr ...

  8. HDU Cow Sorting (树状数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2838 Cow Sorting Problem Description Sherlock's N (1  ...

  9. BZOJ1697: [Usaco2007 Feb]Cow Sorting牛排序

    1697: [Usaco2007 Feb]Cow Sorting牛排序 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 387  Solved: 215[S ...

随机推荐

  1. c#获取今天星期几

    System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.GetDayName(DateTime.Now.DayOfWeek)

  2. Berkeley DB分布式探索

    明天回家就没有网络,今晚就将整个编写过程记录下来.顺带整理思路以解决未能解决的问题. 标题有点托大,想将Berkeley DB做成分布式存储,感觉很高端的样子,实际上就是通过ssh将Berkeley ...

  3. Ubuntu 在未知root密码的情况下修改root密码

    一, 开机按 F12 (或长按Shift), 进入GRUB界面. 二, 在 recovery mode 按e Ubuntu, Linux 3.5.0-17-generic (恢复模式) (或recov ...

  4. PHP弱类型安全问题笔记

    一.类型转换问题    intval(); var_dump(intval('1asdfasd'));  //1 var_dump(intval('awqw12'));  //0 var_dump(i ...

  5. ThoughtWorks FizzBuzzWhizz 代码实现

    当时拉钩网ThoughtWorks出了一道面试题(https://www.jinshuju.net/f/EGQL3D),本人用PHP实现了一下,当时忘记了把代码分享出来,今天特来补上. FizzBuz ...

  6. How to generate number Sequence[AX 2012]

    Suppose we want create number sequence for Test field on form in General  ledger module Consideratio ...

  7. Oracle 动态视图4 V$SESSION_WAIT & V$SESSION_EVENT

    一.视图V$SESSION_WAIT显示了session的当前等待事 Column Datatype Description SID NUMBER Session identifier SEQ# NU ...

  8. line-height属性使文字垂直居中原理

    原理:line-height与font-size的计算之差(在CSS中成为“行间距”)分为两半,分别加到一个文本内容的顶部和底部,这样就使得文字垂直居中了.

  9. 安装mysql 5.5.14 报错

    提示cmake nod foundyum install cmake 原因是曾经服务器安装过mysql数据库Installing MySQL system tables...101223 14:28: ...

  10. iOS中的堆(heap)和栈(stack)的理解

    操作系统iOS 中应用程序使用的计算机内存不是统一分配空间,运行代码使用的空间在三个不同的内存区域,分成三个段:“text segment “,“stack segment ”,“heap segme ...