考题2
描述
给定一个满二叉树,即这棵二叉树有n=2m(0≤m≤18)
个叶子,每个叶子上有一个数字,且从左往右看去,这些数字序列是一个1到n
的排列。
二叉树每个非叶节点都能任意次数地交换左右孩子,且交换没有先后顺序的要求。交换完以后,从左往右看去,叶子组成的数字序列(仍是1到n
的排列)的逆序对可能发生了改变哦~
现在你要求出一种最佳的交换方案,使得叶子组成的数字序列的逆序对数目尽量小。
输入
输入的第一行包含一个正整数n
,这个正整数必为2的幂次。
接下来1行包含n
个整数,一个1到n
的排列,依次表示初始状态下,从左到右看到的叶子上的数字序列。
输出
输出1行1个整数,即最小的逆序对个数。
样例1输入
8
3 1 6 2 8 7 4 5
样例1输出
3
样例1解释
这个二叉树一开始是这样的
a
/ \
/ \
b c
/ \ / \
d e f g
/ \ / \ / \ / \
3 1 6 2 8 7 4 5
经过一系列非叶节点的左右孩子交换:
swap(left(c), right(c))
swap(left(e), right(e))
swap(left(d), right(d))
swap(left(f), right(f))
得到最优的方案:
a
/ \
/ \
b c
/ \ / \
d e g f
/ \ / \ / \ / \
1 3 2 6 4 5 7 8
其叶子组成的数字序列为
1 3 2 6 4 5 7 8
逆序对个数为3。可以验证这个方案是最优的。
样例2
请查看下发文件内的sample2_input.txt和sample2_output.txt。
限制
其中20%的数据,m≤10
;
另外40%的数据,m≤18
;
剩下20%的数据,m≤20
。
时间:2 sec
空间:256 MB
注意,使用python的同学,OJ给你们提供了pypy来提速,源代码根本不用变,只需在第一行修改一下即可享受高速python。
使用pypy必须得在第一行加上(或者直接使用我给你们的IO模板)
python 2:
#!/usr/bin/env pypy
python 3:
#!/usr/bin/env pypy3
提示
为了帮助大家完成题目,我们提供了只包含了输入输出功能的程序模板。
你可以根据自己的实际情况,在这些程序的基础上进行作答,或不参考这些程序,这将与你的得分无关。
这些程序可以从【这里】下载。