HDU 1394 Minimum Inversion Number 线段树和逆序数的应用
2015-06-01 20:58
351 查看
地址:http://acm.hdu.edu.cn/showproblem.php?pid=1394
题意:给出n个数,通过移动,求最小的逆序数对
题解:
1.主要代码:sum = sum + (n - 1 - arr2[i]) - arr2[i]; 2.用线段树求初始数组的逆序数对,然后用上面的代码求出最小的逆序数对
题意:给出n个数,通过移动,求最小的逆序数对
题解:
1.主要代码:sum = sum + (n - 1 - arr2[i]) - arr2[i]; 2.用线段树求初始数组的逆序数对,然后用上面的代码求出最小的逆序数对
#include<iostream> #include<algorithm> using namespace std; #define lx (root<<1) #define rx ((root<<1)|1) #define mid ((left+right)>>1) #define maxs 5010 int arr[maxs]; int arr2[maxs]; int temp[maxs]; int n,sum; void put_up(int left ,int right){ int cur = 1; int i = left; int j = mid + 1; while (i <= mid && j <= right){ if (arr[i] < arr[j]) temp[cur++] = arr[i++]; else{ temp[cur++] = arr[j++]; sum += mid - i + 1; } } while (i<=mid) temp[cur++] = arr[i++]; while (j<=right) temp[cur++] = arr[j++]; for (int k = 1; k < cur;k++){ arr[left++] = temp[k]; } } int update(int root, int left, int right){ if (left == right) return 0; update(lx, left, mid); update(rx, mid + 1, right); put_up(left, right); } int main(){ while (scanf("%d", &n) != EOF){ sum = 0; for (int i = 1; i <= n; i++){ scanf("%d", &arr[i]); arr2[i] = arr[i]; } update(1,1,n); int mins = sum; for (int i = 1; i < n; i++){ sum = sum + (n - 1 - arr2[i]) - arr2[i]; if (mins > sum) mins = sum; } printf("%d\n", mins); } }
相关文章推荐
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- C#数据结构与算法揭秘二
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法
- 基于C++实现的各种内部排序算法汇总
- C++线性时间的排序算法分析
- C++实现汉诺塔算法经典实例
- PHP实现克鲁斯卡尔算法实例解析
- C#常见算法面试题小结
- JavaScript 组件之旅(二)编码实现和算法
- JavaScript数据结构和算法之图和图算法