【算法】数学置换

【题意】给定n个数,要求通过若干次交换两个数的操作得到排序后的状态,每次交换代价为两数之和,求最小代价。

【题解】

考虑置换的定义:置换就是把n个数做一个全排列。

从原数组到排序数组的映射就是经典的置换,这样的置换一定能分解成循环的乘积。

为什么任意置换都可以这样分解:原数组的每个数要交换到排序位置(有后继),每个数的原位置会有数字来替代(有前驱),故一定构成若干循环节。

循环节内要完成置换,需要按顺序依次替换位置进行len-1次对换(len为循环节长度)。

对于每一循环节内部,最高效的方法就是拿最小的数num来进行len-1次交换,代价为sum-num+(len-1)*num即sum+(len-2)*num。

还有一种方法,是从其它循环节拿一个数字(显然拿全局最小)替换当前循环节最小数完成len-1次对换后再换回去,即sum+(len+1)*min+num。

找到每个循环节然后将两个代价中较小者计入答案。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=;
int a[maxn],n,ms,ans=;
bool vis[maxn];
struct cyc{int num,id;}b[maxn]; bool cmp(cyc a,cyc b){return a.num<b.num;}
int main(){
scanf("%d",&n);
ms=0x3f3f3f3f;
for(int i=;i<=n;i++){
scanf("%d",&b[i].num);
b[i].id=i;
ms=min(ms,b[i].num);
}
sort(b+,b+n+,cmp);
for(int i=;i<=n;i++)a[b[i].id]=i;
for(int i=;i<=n;i++)if(!vis[i]){
int sum=,num=0x3f3f3f3f,x=i,len=;
while(!vis[x]){
num=min(num,b[x].num);
sum+=b[x].num;
vis[x]=;
x=a[x];
len++;
}
ans+=min(sum+(len-)*num,sum+num+(len+)*ms);
}
printf("%d",ans);
return ;
}

【BZOJ】1697: [Usaco2007 Feb]Cow Sorting牛排序的更多相关文章

  1. BZOJ 1697: [Usaco2007 Feb]Cow Sorting牛排序

    Description 农夫JOHN准备把他的 N(1 <= N <= 10,000)头牛排队以便于行动.因为脾气大的牛有可能会捣乱,JOHN想把牛按脾气的大小排序.每一头牛的脾气都是一个 ...

  2. BZOJ 1697: [Usaco2007 Feb]Cow Sorting牛排序(置换+贪心)

    题面 Description 农夫JOHN准备把他的 N(1 <= N <= 10,000)头牛排队以便于行动.因为脾气大的牛有可能会捣乱,JOHN想把牛按脾气的大小排序.每一头牛的脾气都 ...

  3. bzoj 1119 [POI2009]SLO && bzoj 1697 [Usaco2007 Feb]Cow Sorting牛排序——思路(置换)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1119 https://www.lydsy.com/JudgeOnline/problem.p ...

  4. bzoj 1697: [Usaco2007 Feb]Cow Sorting牛排序【置换群】

    至今都不知道置换群是个什么东西--题解说什么就是什么.jpg 以下来自hzwer:http://hzwer.com/3905.html #include<iostream> #includ ...

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

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

  6. 【BZOJ】1697: [Usaco2007 Feb]Cow Sorting牛排序(置换群)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1697 置换群T_T_T_T_T_T_T 很久以前在黑书和白书都看过,,,但是看不懂... 然后找了本 ...

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

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

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

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

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

    这是一道置换群的裸题=-=,先拿来试试手对着打,以后应该会更加熟练吧! ; var n,i,j,maxx,minx,now,len,cursum,tmin,sum:longint; p:array[. ...

随机推荐

  1. PAT L2-005 集合相似度

    https://pintia.cn/problem-sets/994805046380707840/problems/994805070149828608 给定两个整数集合,它们的相似度定义为:/.其 ...

  2. thinkphp5学习记录一

    1 使用composer安装 composer create-project topthink/think=5.0.* tpblog --prefer-dist 2 配置环境vim /usr/loca ...

  3. linux+Nginx+Mysql+PHP环境下,安装mysqli模块

    奶奶的腿儿啊,太不易了.倒腾了小半天儿,写此随笔,待后查. 阿里云ecs中,安装phpcms,出现了一个问题:环境检测的时候,一直提示 Mysqli扩展没开启. 老夫哪儿特么会这么专业的啊...能咋办 ...

  4. [剑指Offer] 63.数据流中的中位数

    题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值. c ...

  5. Delphi中正常窗口的实现

    摘要: 在Delphi的VCL库中,为了使用以及实现的方便,应用对象Application创建了一个用来处理消息响应的隐藏窗口.而正是这个窗口,使得用VCL开发出来的程序存在着与其他窗口不能正常排列平 ...

  6. jstack分析线程死锁

    一.介绍 jstack是java虚拟机自带的一种堆栈跟踪工具.jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项&qu ...

  7. CMD (sea.js)模块定义规范

    转自http://www.cnblogs.com/hongchenok/p/3685677.html   CMD 模块定义规范 在 Sea.js 中,所有 JavaScript 模块都遵循 CMD(C ...

  8. BZOJ 1293 生日礼物(尺取法)

    把坐标离散化之后就是很普通的尺取法啦. # include <cstdio> # include <cstring> # include <cstdlib> # i ...

  9. BZOJ 1197 花仙子的魔法(递推)

    数学归纳法. dp[i][j]=dp[i][j-1]+dp[i-1][j-1]. # include <cstdio> # include <cstring> # includ ...

  10. BZOJ4868 Shoi2017期末考试(三分+贪心)

    容易想到枚举最晚发布成绩的课哪天发布,这样与ti和C有关的贡献固定.每门课要么贡献一些调节次数,要么需要一些调节次数,剩下的算贡献也非常显然.这样就能做到平方级别了. 然后大胆猜想这是一个凸函数三分就 ...