Minimize Inversions

先来看看官方题解的做法,他一反常态的没有在逆序对题目里面考虑每个位置的贡献,而是直接回到定义考虑每对数是否是逆序对

我们考虑原数列中任意的一组数(ai,aj)(bi,bj)。如果最开始两个都不是逆序对,那么交换之后两个都是逆序对;如果最开始两个都是逆序对,那么交换之后两个都不是逆序对;如果最开始一个是逆序对另外一个不是,那么交换之后仍然如此

最后一种情况的一组数无论怎么交换他对答案的贡献都是不会变化的,所以我们不用考虑;而前面两种组合,我们肯定要尽量的让交换后都不是逆序对的数量更多,而这显然是可以达到的,最后的序列中如果存在一组数(ai,aj)(bi,bj)而且这两对数都是逆序对,那么我们交换一下就好了

我们以ai为关键字排序,就可以数出来是满足题意的(当然这道题目放在B也应该猜到这么做)

再来看看我的证明,仍然是考虑每一个位置的贡献

首先,交换ij的操作肯定可以等价于交换若干次相邻的数对,所以为了简化问题,我们考虑每次操作交换相邻的两个数的情况

(ai,ai+1)(bi,bi+1),如果前者是逆序对但是后者不是,我们交换之后总逆序对数不变;如果前者不是逆序对但是后者是,我们交换之后总逆序对数不变;如果两个都不是逆序对,交换之后逆序对个数加二;如果两个都是逆序对,交换之后逆序对个数减二

也就是说对任意的序列,如果把其按照ai为关键字进行排序交换(像冒泡排序那样),那么每次的交换操作不会让总逆序对数增加,可能会减少,所以最优的序列一定可以把它弄成按照ai为关键字排序的样子

posted @   最爱丁珰  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示