poj1804 Brainman **

/*
* 逆序对-poj-1804.cpp
*
* 由于只能交换相邻的两个数,所以答案就是该序列的逆序对数
*
* 分治, 归并排序的框架
*
*/
#include <cstdio>
using namespace std;

const int maxn = 1000 + 5;
int n, num[maxn], tot;
int t[maxn];

//通过归并排序,求num[p..q]之间的逆序对
void cal(int p, int q){
if(p == q) return;

int mid = (p + q) / 2;
cal(p, mid);

cal(mid+1, q);

for(int i=p; i<=q; i++)
t[i] = num[i];

int a = p, b = mid+1, i=p;
while(a <= mid || b <= q){
if(b > q || (a <= mid && t[a] <= t[b])) num[i++] = t[a++];
else{
tot += (mid - a + 1); //左边所有比t[b]大的数分别与t[b]构成逆序对
num[i++] = t[b++];

}
}

}


int main(){
int caseNum = 0, k=1;
scanf("%d", &caseNum);

while(k <= caseNum){
if(k != 1) printf("\n");
scanf("%d", &n);
for(int i=0; i<n; i++)
scanf("%d", &num[i]);

tot = 0;
cal(0, n-1);

printf("Scenario #%d:\n%d\n", k, tot);
k++;
}

return 0;
}
原文地址:https://www.cnblogs.com/longdouhzt/p/2275380.html