【挑战程序设计竞赛】分治法求一个数列逆序对的对数
2013-10-04 16:03
316 查看
此题来源于冒泡排序需要交换的次数,在冒泡排序中,我们需要交换两个元素的位置的情况是:对于位置
(i<j)有a[i]>a[j],我们称这是一对逆序数,我们就要求一个数列中满足这样条件的对数,当然采用暴力法两重的
for循环当然可以做到,复杂度是O(n^2),我们采用分治法,类似于合并排序的思想:
(i<j)有a[i]>a[j],我们称这是一对逆序数,我们就要求一个数列中满足这样条件的对数,当然采用暴力法两重的
for循环当然可以做到,复杂度是O(n^2),我们采用分治法,类似于合并排序的思想:
#include <iostream> #include <vector> using namespace std; typedef long long LL; LL merge_cnt(vector<int> &input) { int n = input.size(); if(n <= 1) return 0; LL cnt = 0; vector<int> left(input.begin(),input.begin() + n/2); //划分 vector<int> right(input.begin() + n/2,input.end()); cnt += merge_cnt(left); cnt += merge_cnt(right); int ai = 0, bi = 0, ci = 0; while(ai < n) { if(bi < left.size() && (ci == right.size() || left[bi] <= right[ci])) { input[ai++] = left[bi++]; } else { cnt += n/2 - bi; // 对于数列right的每一个元素,统计left中 // 大于此元素的个数,此时两个数列是已经排好序的 input[ai++] = right[ci++]; } } return cnt; } int main() { int a[4]={3,1,4,2}; vector<int> input(a,a+4); cout<<merge_cnt(input)<<endl; for(int i = 0; i < input.size(); i++) { cout<<input[i]<<" "; } cout<<endl; }
相关文章推荐
- 挑战程序设计竞赛 算法和数据结构 第6章 递归和分治法
- poj3061 尺取法 <挑战程序设计竞赛>
- poj3276 反转 挑战程序设计竞赛
- 分治法求一个N个元素数组的逆序数
- [挑战程序设计竞赛] AOJ 0558 - Cheese
- 挑战程序设计竞赛 2.6 数学问题的解题窍门
- poj1064 二分搜索 挑战程序设计竞赛
- 山东省第四届ACM大学生程序设计竞赛Rescue The Princess(一个点绕另一个点的旋转)
- 挑战程序设计竞赛(第2版)pdf
- 【HDU5927 2016CCPC东北地区大学生程序设计竞赛 - 重现赛 F】【dfs序 + 线段树 or 树状数组 复杂度计算】Auxiliary Set 一个点如果是好点或是两个好点的LCA就是好
- 二分图(挑战程序设计竞赛)
- 算法思想学习系列:分治法——求数列的逆序数
- ACM Curling 2.0(挑战程序设计竞赛)
- 挑战程序设计竞赛 2.1迷宫的最短路径
- [挑战程序设计竞赛] AOJ 0525 - Osenbei
- [挑战程序设计竞赛] POJ 1328 - Radar Installation
- 挑战程序设计竞赛 部分和问题
- 挑战程序设计竞赛——1.61三角形
- poj2376 区间贪心 <挑战程序设计竞赛>
- [挑战程序设计竞赛] POJ 3040 - Allowance