首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

【挑战程序设计竞赛】分治法数列逆序对的对数

2013-10-06 
【挑战程序设计竞赛】分治法求一个数列逆序对的对数此题来源于冒泡排序需要交换的次数,在冒泡排序中,我们需

【挑战程序设计竞赛】分治法求一个数列逆序对的对数

此题来源于冒泡排序需要交换的次数,在冒泡排序中,我们需要交换两个元素的位置的情况是:对于位置

(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;}


热点排行