关于“相邻交换法”
来源:互联网 发布:鸟哥php 编辑:程序博客网 时间:2024/06/07 06:01
相邻交换法(名字来自白书)主要解决元素排列问题,基本思路是先考虑两个元素如何决定先后,再推广到全体。
例1.NOIP2012国王游戏
容易发现对于相邻的i,j,若ai*bi>=aj*bj则i在j之前。
现在要推广到全体,需要先证明一个结论:
不妨把满足任意i在j之前的i,j都有ai*bi>=aj*bj称为S排列。
则S排列是最优排列。
证明:
易知对于相邻i,j,i在j之前,交换不影响其他元素,且若ai*bi<=aj*bj,把i,j交换一定不会变差,我们把这样的交换称为好操作。
只需证任意排列可以通过一系列好操作变成S排列,因为这意味着S排列不比任意排列差,即S排列是最优排列。
变换方法如下:对于一个排列,先挑ai*bi最大的,一路交换到最后,再挑第二大的,交换到倒数第二,以此类推。易知这当中的所有操作都是好操作。
从而S排列是最优排列,按ai*bi排序即可得到。
例2.UVa10905 Children’s Game
先考虑两个相邻元素A,B,设A的位数为LA,LB同理。
则若A*10^LB+B<=B*10^LA+A,那么A应在B之前。
同上,我们需要找S排列(也可能不存在)
对上式变形,有(10^LB-1)/B<=(10^LA-1)/A
那么(10^i-1)*i和例1的ai*bi是同理的,按它排序即可。
例3.二元流水作业调度问题
经典问题。
国际惯例先考虑两个相邻元素。
i在j之前的条件:min{bi,aj}>=min{bj,ai}
同样的问题:构造S排列。
遗憾的是上述条件和i,j都相关,没办法分成只与其中一个相关的量。
之前的办法行不通了。
只能再从上式入手。
发现:把所有ai,bi中最小的找出来,设它是ax,则由上式知任意元素都应排在x它之后,即它排最前。同理,若它是bx,则排最后。
像这样一直做下去,易知最后的排列是S排列,即最优排列。
- 关于“相邻交换法”
- 交换相邻法(2)
- 相邻交换
- uva 11269 - Setting Problems(相邻交换法)
- uva 10327 相邻数字交换排序法
- 单链表交换相邻元素
- 交换链表相邻节点
- 交换链表中的相邻节点
- 交换单向链表的相邻节点
- 交换单链表中相邻的两个点(人搜)
- 单链表相邻两个节点之间交换顺序
- Leetcode016--链表相邻元素进行交换
- 交换链表中相邻节点的位置
- 关于JQ获取同级元素问题(相邻、不相邻)
- javascript冒泡排序方法并统计相邻数交换次数
- 交换单链表中相邻的两个元素 Swap Nodes in Pairs
- 8.通过调整链来交换两个相邻的元素
- Swap Nodes in Pairs 链表交换相邻的节点
- HDU 1272 小希的迷宫
- 使用C#详解常用排序算法(二):插入排序(Insert Sort)
- 协议和继承的关系
- 设计模式学习之---模板方法设计模式
- 线程--具体函数介绍
- 关于“相邻交换法”
- Linux基础知识全面总结
- Hadoop的家族成员
- IOS学习之蓝牙4.0 BLE
- runtime自定义
- 开源小小调试器-MiniDebugger
- HDU 1282 回文数猜想
- 消息队列
- Linux 利用管道父子进程间传递数据