1394.Minimum Inversion Number(HDU)

16 篇文章 0 订阅

题意理解

给定一个长度N的全排列,对这样的一个序列对应一个逆序数;现在每次将第一个数放到序列最后一位,形成一个新的序列,这个新序列也对应一个逆序数。求所有这些放法对应逆序数的最小值。逆序数定义:对于i<j,a[i]>a[j]。

问题分析

用树状数组数据结构

转一:问题分两层解决,一是求单个序列的逆序数,而是求n个序列逆序数的最小值

转二:求单个序列的逆序数。就是把序列每个数的逆序数加起来,对于单个数的逆序数,理解为这个数前面从第一位开始到它自己,有几个数比它大,有几个算几个逆序数。再进一步理解,计算它前面有几个数比它大,可以转化为前面数的总数量减去前面比它小的数的个数。总数量就是这个数所在的序号减1,前面比它小的数的个数计算方法是每遍历序列中一个数,就做一个标记为1,表示数已经存在,数一下这些标记的数量就是比它小的数的个数。这是一个前缀和。复杂度O(nlogn)

转三:求n个序列逆序数的最小值。常见思路是一次遍历序列,总复杂度O(n^2logn)。前后两个序列变化点在于,第一个数放到最后一位。从这个角度出发,影响分为三方面,这个数本身的逆序数,这个数前面的逆序数和,这个数后面的逆序数和。第一个数所在位置后面的数没有影响,因为这个数都小于后面的数,不构成逆序对;而第一个数所在位置的前面的每个数都会少一个逆序数,因为比它小的数都少了一个比它大的数;这个数本身的逆序数变大了,从0到n-1-a[i],所有比它的数都构成了逆序对。算法复杂度为O(nlogn+n)=O(nlogn).

参考:https://blog.csdn.net/ssimple_y/article/details/53744096

其他

这题思路巧,没思路,问了同学才理解,自己很难想到。

直接求不行,转化为差值

直接求不行,用变化值分析逐步来求解

灵活用数组下标,一次遍历记录已经处理的信息,善于利用这些信息求目标解。

代码链接

https://github.com/xierensong/learngit/blob/master/hdu/h1394.cpp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值