题意:给你一个无序数列,让你两两交换将其排成一个非递减的序列,每次交换的花费交换的两个数之和,问你最小的花费

思路:首先了解一下什么是置换,置换即定义S = {1,...,n}到其自身的一个双射函数f。那么我们将其写为若干个不相交的循环的乘积形式(A1, A2, ... Ap1)(B1, B2, ... Bp2)... ...例如

数组   9 4 5 7 3 1

下标   1 2 3 4 5 6

排序后下标   6 3 4 5 2 1

让我们看下标 1->6->1 一个循环 (9 1)

2->3->4->5->2       一个循环(4 5 7 3)、

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

我们可以用一个贪心的思想,每次用循环最小的那个数进行两两交换,定义循环的所有数总和为sum,循环的最小值为k,循环长度为len,那么一个循环的花费为 sum-k+(len-1)*k => sum+(len-2)*k

但是其实还有另一种可能,用整个置换最小的那个和这个循环最小的进行换位,定义循环的所有数总和为sum,循环的最小值为k,循环长度为len,整个置换的最小值为kmin ,,那么一个循环的花费为 sum+(len+1)*kmin+k

每一次循环的最小值为 ans=ans+min(sum+(len-2)*k,sum+(len+1)*kmin+k)

组合数学置换资料https://wenku.baidu.com/view/9b8d9d32e87101f69e3195f8.html

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#define maxn 100005
using namespace std; struct node
{
int num;
int id;
}; bool cmp(node a,node b)
{
if(a.num<b.num) return true;
else return false;
} int main()
{
node data[maxn];
int visit[maxn];
int n;
int minn=<<;
int ans=;
while(scanf("%d",&n)!=-)
{
for(int i=;i<n;i++)
{
scanf("%d",&data[i].num);
data[i].id=i;
minn=min(minn,data[i].num);
}
memset(visit,,sizeof(visit));
sort(data,data+n,cmp);
for(int i=;i<n;i++)
{
if(!visit[i])
{
visit[i]=;
int tmp=data[i].id;
int kmin=data[i].num;
int sum=data[i].num;
int len=;
while(tmp!=i)
{
visit[tmp]=;
len++;
sum+=data[tmp].num;
kmin=min(kmin,data[tmp].num);
tmp=data[tmp].id;
}
ans+=min(sum+kmin*(len-),sum+(len+)*minn+kmin);
}
}
printf("%d\n",ans);
}
return ;
}

poj 3270 Cow Sorting (置换入门)的更多相关文章

  1. POJ 3270 Cow Sorting(置换群)

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

  2. poj 3270 Cow Sorting

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

  3. POJ 3270 Cow Sorting(置换群)

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

  4. 【POJ】3270.Cow Sorting

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

  5. Cow Sorting(置换)

    http://poj.org/problem?id=3270 // File Name: poj3270.cpp // Author: bo_jwolf // Created Time: 2013年1 ...

  6. poj 3270(置换 循环)

    经典的题目,主要还是考思维,之前在想的时候只想到了在一个循环中,每次都用最小的来交换,结果忽略了一种情况,还可以选所有数中最小的来交换一个循环. Cow Sorting Time Limit: 200 ...

  7. Cow Sorting(置换群)

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

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

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

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

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

随机推荐

  1. Spark 键值对RDD操作

    键值对的RDD操作与基本RDD操作一样,只是操作的元素由基本类型改为二元组. 概述 键值对RDD是Spark操作中最常用的RDD,它是很多程序的构成要素,因为他们提供了并行操作各个键或跨界点重新进行数 ...

  2. Asp.net MVC4 ExtJS权限管理系统源码 C#开发框架源码

    开发环境:VS2010或以上 数据库:SQL Server 2008 r2 MVC版本:Asp.net mvc 4.0 ExtJs版本:ext-4.2   功能介绍 1.多标签,js动态加载模式,全a ...

  3. 第八讲:I/O虚拟化

    一.I/O虚拟化的产生 服务器单个千兆以太网端口肯定能够支持单个应用,但是当被分割为10个.15个或者更多的服务器负载时(这其中包括网络.存储以及服务器之间的流量)可能就不够用了. 当遇到I/O瓶颈时 ...

  4. DTD验证XML文档

    DTD验证XML文档        1.DTD简介:DTD是Document Type Definition的缩写,即文档定义            1.1:DTD的内容包含:             ...

  5. 局域网里连接mysql服务器,其他人连接自己的mysql服务器

    应用场景:  自己在自己的机器上开发网站,同事也要和我一起开发,就两个人,我自己的机器当做服务器,让他直接连我的数据库,看我的项目就行了,并且用svn进行开发,相当不错 问题: 怎样在局域网里,其他人 ...

  6. 用PHP ping 一个 IP

    最近要做一个 测试IP列表 是否能连通的功能.大家都知道我们一般用 ping 命令就可以看到IP端口可不可以连通.那在程序里要怎么做呢? 我们在网上找到很多都是使用  exec("ping ...

  7. mongoDB & Nodejs 访问mongoDB (二)

    非常详细的文档http://mongodb.github.io/node-mongodb-native/2.2/quick-start/quick-start/ 连接数据库 安装express 和 m ...

  8. Visual Studio 2017 通过SSH 调试Linux 上.NET Core

    Visual Studio 2017 通过SSH 调试Linux 上.NET Core 应用程序. 本文环境 开发环境:Win10 x64 Visual Studio 2017 部署环境:Ubuntu ...

  9. 循环单词 java

    链接:https://www.nowcoder.com/questionTerminal/9d5fbe7750a34d0b91c73943f93b2d7d来源:牛客网如果一个单词通过循环右移获得的单词 ...

  10. linux codeblocks汉化

    参考window汉化codeblocks,linux下有点麻烦,就是要找到codeblocks的文件安装在哪里.一般来说,linux下安装的软件大都在/usr/share/文件夹下,所以进入/usr/ ...