申明:全文参考巫泽俊《挑战程序设计》
算法思想:分治法,通过将问题划分为规模更小的子问题,递归地解决划分后的子问题,再将结果合并从而高效地解决问题
问题:
求一个数列A的逆序数
思路
代码
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
ll merge_count(vector<int> &a){
int n = a.size();
if (n <= 1) return 0;
ll cnt = 0;
vector<int> b(a.begin(), a.begin() + n/2);
vector<int> c(a.begin() + n / 2, a.end());
cnt += merge_count(b); //(1)
cnt += merge_count(c); //(2)
//此时,b和c已经分别排好序了
//(3)
int ai = 0, bi = 0, ci = 0;
while(ai < n){
if (bi < b.size() && (ci == c.size() || b[bi] <= c[ci])){
a[ai++] = b[bi++];
}else {
cnt += n/2 - bi;
a[ai++] = c[ci++];
}
}
return cnt;
}
int main(){
vector<int> A;
int a[] = {1, 2, 5, 7, 2, 9, 2, 3};
for(int i = 0; i < sizeof(a)/sizeof(int); i++){
A.push_back(a[i]);
}
printf("%lld\n", merge_count(A));
}