博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj3270
阅读量:7289 次
发布时间:2019-06-30

本文共 1240 字,大约阅读时间需要 4 分钟。

终于把这个很久以前拖下来的问题解决了

回忆一下,最少相邻交换次数等于逆序对数

这里求的是最少交换代价(非相邻元素也可以交换);

先考虑最少交换次数这个问题

首先把现在数列看成原数列{1,2,3……n}的一个置换

根据置换的理论,每一个置换都能拆成唯一的互不相交的循环

显然最小交换次数是在每个循环内部交换达成的

在一个包含元素数位x的循环内,交换成原数列的最小次数显然为x-1

最小交换次数就很明显了

而这里求的是最小交换代价,显然循环内部每个元素都要交换一次(除了只含一个元素的循环)

首先想到的是用每个循环内最小元素使循环内其他元素归位

注意还有一种情况,我们可以把整个序列里的最小元素a和这个循环里最小的b交换,然后用元素a与循环内其他元素交换,最后再把

a交换出循环(a和b交换)

最小代价就是取这两种方法较小的那一个

1 var a,b:array[0..10010] of longint; 2     f:array[0..100010] of longint; 3     v:array[0..100010] of boolean; 4     t,x,max,i,n,s,ans:longint; 5  6 function min(a,b:longint):longint; 7   begin 8     if a>b then exit(b) else exit(a); 9   end;10 11 procedure dfs(x:longint);   //找循环12   begin13     v[x]:=true;14     ans:=ans+a[x];15     inc(s);16     if not v[b[x]] then dfs(b[x]);17   end;18 19 begin20   readln(n);21   for i:=1 to n do22   begin23     readln(x);24     if x>max then max:=x;25     f[x]:=i;26   end;27   for i:=1 to max do  28     if f[i]>0 then29     begin30       inc(t);31       b[f[i]]:=t;32       a[t]:=i;33     end;34 35   for i:=1 to n do36     if not v[i] then37     begin38       s:=0;39       dfs(i);40       ans:=ans+min((s-2)*a[i],(s+1)*a[1]+a[i]);41     end;42 43   writeln(ans);44 end.
View Code

 

转载于:https://www.cnblogs.com/phile/p/4473188.html

你可能感兴趣的文章
冒泡排序
查看>>
(七)Action访问Servlet API
查看>>
POJ2960 S-Nim(博弈论:sg函数)
查看>>
$().each()和$.each()
查看>>
iconfont字体图标
查看>>
AndroidStudio下加入百度地图的使用 (三)——API基本方法及常量属性
查看>>
二、2、上传成功也不一定得到flag哦!
查看>>
火狐浏览器设置placeholder的时候记得改opacity
查看>>
Mina学习
查看>>
java通过句柄访问对象
查看>>
extern "C"与C++中的C函数调用(4)—— 如何在C中调用C++函数
查看>>
计算几何 模板
查看>>
“The Psychology of Cross Country”笔记
查看>>
10 Web Apps for Developers 为开发者提供的10款Web应用程序
查看>>
python之正则表达式
查看>>
Shell命令-文件及目录操作之touch、tree
查看>>
修改K/3 Cloud管理中心端口
查看>>
C#语言课程11月7日
查看>>
linux日常1-踢出用户
查看>>
MFC多文档应用程序同时显示两个视图
查看>>