给定有序数组a[1...n]的一个置换a[σ(1)...σ(n)], 通过交换数组元素把置换后的数组恢复为有序,

定义进行一次交换的代价为两元素之和,试问此过程的最小总代价。

实际上一种置换即定义S = {1,...,n}到其自身的一个双射函数f。

可以证明必然存在整数k使得f^k = f0 = I。即存在周期性。

实际上此函数的幂存在局部周期性,即存在若干个互不相交循环单位,S中每个元素恰属于其中一个循环节。

例如考虑:f:u(1,2,3,4,5,6,7) -> v(3,6,7,5,1,2,4)

将循环单位极小化:(3,7,5,1,4)(6,2)。

循环节内的元素按其在v中的位置排列。

我们的目标是将其调整为(1,3,4,5,7)(2,6)。

循环节内的每一个元素都在不合适的位置上,因此长度为l循环节内部至少需要进行(l - 1)次互换可使其有序。

考虑长度为l的循环节:

由于所有元素均需要调整,因此循环节内部调整代价的一个下界是循环节内所有元素之和加上最小元素与交换次数的乘积。

可以达到该下界:

例考虑调整(3,7,5,1,4),由于1占据了5应该所处的位置,(5,1)交换得到(3,7,1,5,4)。

如此不断迭代将其整理为有序所需代价为min_value * (l - 2) + sum_value(*)。

由于循环节内部调整相互独立,即可以分步进行,考虑利用非循环节内部元素进一步降低代价。

交换循环节外部一元素a(取最小的元素显然更优)和循环节内部一元素b,如此总代价为:

2 * (a + b) + a * (l - 2) + sum_value - b + a = b + a * (l + 1) + sum_value(#),

由于a取外部最小值,b取内部最小值,(#)可能会优于(*)。

(#)-(*) = a * (l + 1) - (l - 3) * b = (l + 1) * (a - b) + 4 * b,

由于已经引入全局最小值,若再次交换则必有a > b,只会增加代价。

因此最多交换一次。

这样本题就可以给出答案了。

http://poj.org/problem?id=3270

 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1e4 + ;
const int inf = 0x3f3f3f3f;
int f[maxn];
int a[maxn], n, mini;
bool vis[maxn]; void solve(){
memset(vis, , sizeof vis);
int ans = ;
for(int i = ; i < n; i++){
if(vis[i]) continue;
vis[i] = ;
int len = , minii = a[i], sum = a[i];
int j = f[i];
while(j != i){
vis[j] = ;
sum += a[j];
++len;
minii = min(minii, a[j]);
j = f[j];
}
ans += (len - ) * minii + sum + min(, (len + ) * (mini - minii) + * minii);
}
printf("%d\n", ans);
} bool cmp1(int u, int v) { return a[u] < a[v]; } int main(){
freopen("in.txt", "r", stdin);
while(~scanf("%d", &n)){
mini = inf;
for(int i = ; i < n; i++){
scanf("%d", &a[i]);
mini = min(a[i], mini);
}
for(int i = ; i < n; i++) f[i] = i;
sort(f, f + n, cmp1);
solve();
}
return ;
}

poj3270 Cow Sorting的更多相关文章

  1. 【置换群】poj3270 Cow Sorting

    并不应该叫置换群……只是用到了置换而已,并没有群. 题解看这个吧,我就不写了:http://www.cnblogs.com/kuangbin/archive/2012/09/03/2669013.ht ...

  2. HDU Cow Sorting (树状数组)

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

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

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

  4. Cow Sorting(置换群)

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

  5. hdu 2838 Cow Sorting(树状数组)

    Cow Sorting Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  6. Cow Sorting hdu 2838

    Cow Sorting Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  7. BZOJ_1697_[Usaco2007 Feb]Cow Sorting牛排序_贪心

    BZOJ_1697_[Usaco2007 Feb]Cow Sorting牛排序_贪心 Description 农夫JOHN准备把他的 N(1 <= N <= 10,000)头牛排队以便于行 ...

  8. 树状数组 || 线段树 || Luogu P5200 [USACO19JAN]Sleepy Cow Sorting

    题面:P5200 [USACO19JAN]Sleepy Cow Sorting 题解: 最小操作次数(记为k)即为将序列倒着找第一个P[i]>P[i+1]的下标,然后将序列分成三部分:前缀部分( ...

  9. 【BZOJ 1697】1697: [Usaco2007 Feb]Cow Sorting牛排序

    1697: [Usaco2007 Feb]Cow Sorting牛排序 Description 农夫JOHN准备把他的 N(1 <= N <= 10,000)头牛排队以便于行动.因为脾气大 ...

随机推荐

  1. LinkedHashMap 和 LRU算法实现

    个人觉得LinkedHashMap 存在的意义就是为了实现 LRU 算法. public class LinkedHashMap<K,V> extends HashMap<K,V&g ...

  2. SQL百分比

    百分比=cast(cast(count(ProvinceName)*100./ (select count(Id) from  dbo.TopicCurrent   where boardId=316 ...

  3. Lintcode: Segment Tree Modify

    For a Maximum Segment Tree, which each node has an extra value max to store the maximum value in thi ...

  4. 转:python webdriver API 之定位一组对象

    webdriver 可以很方便的使用 find_element 方法来定位某个特定的对象,不过有时候我们却需要定位一组对象,WebElement 接口同样提供了定位一组元素的方法 find_eleme ...

  5. Hibernate二进制或大文件类型数据和Oracle交互

    //测试存储二进制文件 @Test public void test() throws IOException{  InputStream in=new FileInputStream("E ...

  6. OpenStack 镜像制作

    Contents [hide] 1 Centos6.5 img制作 1.1 基础环境安装 1.2 下载或从本地上传系统镜像 1.3 启动服务 1.4 建立镜像文件 1.5 通过virt-install ...

  7. 忘记 oracle11g 的 sys 密码的处理

    方法1: 利用oracle 的本地用户信任方式登录,修改sys密码,具体如下: 1.检查 oracle 的network/admin 下的 sqlnet.ora 文件内, 存在 SQLNET.AUTH ...

  8. TI BLE CC2541的I2C主模式

    由于要写TM1680, 写命令跟写数据, 所以需要使用CC2541的I2C, 2541是有硬件I2C的. tm1680.c: #include "tm1680.h" //TM168 ...

  9. JDBC的几种驱动

    不同的数据库的驱动是不同的 其中:Access驱动串---------sun.jdbc.odbc.JdbcOdbcDriver    MySQL驱动串---------com.mysql.jdbc.D ...

  10. test if DEMO

    可参考:http://blog.chinaunix.net/uid-20671208-id-3643362.html 1.test 举例: test -d ~/auto && echo ...