HDU-1394-Minimum Inversion Number
2017-01-11 18:37
375 查看
ACM模版
这个问题简化看来就是求逆序数,先求原始状况逆序数,其他可以递推出来,假设初始序列逆序数个数为 N 个,那么将序列首放到序列尾,逆序数会减少 A[i] 个,然后另外增加 N-(A[i]+1) 个,枚举所有状态,获取最优解即可。
所以问题的关键只剩下第一个如何求逆序数,方法有很多,因为 n 比较小,所以可以暴力,高效一些的方法也有,线段树可解,当然,求逆序数比较常用的方法还是要数归并排序求逆序数了,一个模板解决。鉴于最近在做线段树专项训练,所以用线段树解了一下下,结点插入,区间求和~~~
描述
题解
题意一开始没看懂,懵了许久,而后了解到,一个由 0~n-1 组成的序列,每次都可以把队首的元素移动到队尾,求形成的 n 个序列中最小逆序对数目。这个问题简化看来就是求逆序数,先求原始状况逆序数,其他可以递推出来,假设初始序列逆序数个数为 N 个,那么将序列首放到序列尾,逆序数会减少 A[i] 个,然后另外增加 N-(A[i]+1) 个,枚举所有状态,获取最优解即可。
所以问题的关键只剩下第一个如何求逆序数,方法有很多,因为 n 比较小,所以可以暴力,高效一些的方法也有,线段树可解,当然,求逆序数比较常用的方法还是要数归并排序求逆序数了,一个模板解决。鉴于最近在做线段树专项训练,所以用线段树解了一下下,结点插入,区间求和~~~
代码
#include <iostream> #include <cstdio> using namespace std; const int MAXN = 5555; int sum[MAXN << 2]; void pushUp(int root) { sum[root] = sum[root << 1] + sum[root << 1 | 1]; } void build(int root, int l, int r) { sum[root] = 0; if (l == r) { return ; } int m = (l + r) >> 1; build(root << 1, l, m); build(root << 1 | 1, m + 1, r); } void update(int root, int val, int l, int r) { if (l == r) { sum[root]++; return ; } int m = (l + r) >> 1; if (val <= m) { update(root << 1, val, l, m); } else { update(root << 1 | 1, val, m + 1, r); } pushUp(root); } int query(int L, int R, int l, int r, int root) { if (L <= l && r <= R) { return sum[root]; } int m = (l + r) >> 1; int ret = 0; if (L <= m) { ret += query(L, R, l, m, root << 1); } if (R > m) { ret += query(L, R, m + 1, r, root << 1 | 1); } return ret; } int A[MAXN]; int main(int argc, const char * argv[]) { int n; while (~scanf("%d", &n)) { build(1, 0, n - 1); int sum = 0; for (int i = 0; i < n; i++) { scanf("%d", A + i); sum += query(A[i], n - 1, 0, n - 1, 1); update(1, A[i], 0, n - 1); } int ret = sum; for (int i = 0; i < n; i++) { sum += n - A[i] - A[i] - 1; ret = min(ret, sum); } printf("%d\n", ret); } return 0; }
相关文章推荐
- HDU 1394 Minimum Inversion Number(线段树:单点更新,区间求和)
- HDU-1394 Minimum Inversion Number 树状数组
- HDU - 1394 Minimum Inversion Number【逆序数+dp】
- hdu 1394 Minimum Inversion Number(线段树)
- hdu 1394 Minimum Inversion Number
- HDU 1394 Minimum Inversion Number 线段树
- hdu 1394——Minimum Inversion Number
- hdu 1394 Minimum Inversion Number
- hdu 1394 Minimum Inversion Number
- HDU 1394 Minimum Inversion Number(线段树求逆序对数)
- HDU 1394 Minimum Inversion Number
- hdu 1394 Minimum Inversion Number(线段树求最小逆序数)
- hdu 1394 Minimum Inversion Number(线段树+逆序对)
- ZOJ 1484 HDU 1394 Minimum Inversion Number / 线段树单点更新
- HDU 1394(线段树) Minimum Inversion Number
- hdu1394 Minimum Inversion Number
- HDU:1394 Minimum Inversion Number(树状数组+逆序对)
- HDU 1394 Minimum Inversion Number(树状数组)
- hdu 1394 Minimum Inversion Number
- hdu 1394 Minimum Inversion Number(逆序数)