交换

3.1 Problem Statement
小 D 正在研究交换。
小 D 认为一个整数序列是好的,当且仅当它先(不严格)上升,后(不严格)下
降。形式化地,我们认为序列 a1, a2, · · · , an 是好的,当且仅当存在某个 k ∈ [1, n],使
得对于任意 1 ≤ i < k,有 ai ≤ ai+1;且对于任意 k ≤ i < n,有 ai ≥ ai+1。
小 D 得到了一个长度为 n 的序列 a1, a2, · · · , an,他想让这个序列变成好的。
小 D 每次可以交换相邻的两个元素。因为交换很累,所以小 D 想知道,他最少
需要交换多少次。
这下小 D 不会了,请你帮帮他。

3.2 Input Format
从标准输入读入数据。
第一行一个正整数 n,表示序列的长度。
第二行 n 个空格隔开的整数 a1, a2, · · · , an,表示初始的序列。

3.3 Output Format
向标准输出输出答案。
输出一行一个整数,表示最小交换次数。

3.4 Sample 1
3.4.1 Input
6
6 5 1 3 2 4
3.4.2 Output
4

3.4.3 Explanation
一组最优解如下:
• 交换 a5, a6,得到 a = [6, 5, 1, 3, 4, 2];
• 交换 a4, a5,得到 a = [6, 5, 1, 4, 3, 2];
• 交换 a2, a3,得到 a = [6, 1, 5, 4, 3, 2];
• 交换 a1, a2,得到 a = [1, 6, 5, 4, 3, 2]。

3.5 Sample 2
见下发文件 swap/swap2.in 与 swap/swap2.ans。
3.6 Sample 3
见下发文件 swap/swap3.in 与 swap/swap3.ans。

3.7 Constraints
对于所有测试数据,1 ≤ n ≤ 3 × 105,1 ≤ ai ≤ n。
• 子任务 1(15 分):n ≤ 10;
• 子任务 2(20 分):n ≤ 500;
• 子任务 3(15 分):n ≤ 5000;
• 子任务 4(15 分):n ≤ 105;
• 子任务 5(20 分):{a} 是一个 [1, n] 的排列;
• 子任务 6(15 分):无特殊限制。

题解:
首先,前置知识:对于一个序列,只能相邻两两交换时,拍成有序序列的最小次数为逆序对的个数。
这时看到这道题,假如我们知道了每个数在序列中的排名,且确定了最终的某个可能最优解时(单峰函数),我们把下标重新赋给每个数,这时的最小次数就是下标的逆序对数。
证明考虑微扰相邻。
假如现在改变最优解,且之变动一个数x时:
这时x有两种可能,一最后在最大值的左侧,二最后在右侧。且我们又能发现无论怎么变动,x对于比它权值小的数大小情况都不会改变,所以只考虑比x大的数。
这时我们发现,在左侧时,x与x左侧的权值比它大的数构成逆序对;在右侧时,x与x右侧权值比它大的数构成逆序对。
所以综上,应对每个数统计左侧大的数和右侧大的数,取个数最小值。

#include<iostream>
#include<cstring>
#include<algorithm>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值