Problem地址:http://poj.org/problem?id=2299
这题题意:给一对序列,通过调换相邻元素位置的方法,将一组无序数据排序成递增有序数据。
这里有一个结论:通过调换相邻元素位置的方法,将一组无序数据排序成递增有序数据的最小调换次数为此组数据中逆序对的对数。这里不证明这个结论。
那么这题就变成求这组数据中逆序对的对数。
求逆序对的方法很多,我采用了基于归并排序的方法,参考自此网页:http://blog.csdn.net/morewindows/article/details/8029996
#include <iostream> #include <cstring> #include <cstdio> const int MAXN = 500000 + 50; int array[ MAXN ]; int tmp[ MAXN ]; long long counter; void MergeArray( int first, int mid, int end ) { int i = first, j = mid+1; int pointer = 0; while( i <= mid && j <= end ) { if( array[i] < array[j] ) { tmp[ pointer ++ ] = array[ i ++ ]; } else { tmp[ pointer ++ ] = array[ j ++ ]; counter = counter + mid - i + 1; } } while( i<=mid ) { tmp[ pointer ++ ] = array[ i ++ ]; } while( j<=end ) { tmp[ pointer ++ ] = array[ j ++ ]; } for( i=0; i<pointer; i++ ) { array[ i + first ] = tmp[ i ]; } } void MergeSort( int begin, int end ) { if( begin < end ) { int mid = ( begin + end ) >> 1; MergeSort( begin, mid ); MergeSort( mid+1 , end ); MergeArray( begin, mid, end ); } } int main() { int N; while( scanf( "%d", &N ) != EOF && N ) { counter = 0; for( int i=0; i<N; i++ ) { scanf( "%d", &array[i] ); } MergeSort( 0, N-1 ); printf( "%lld\n", counter ); } return 0; }
原文:http://www.cnblogs.com/Emerald/p/4418617.html