题目:给出一个数列,每次交换相邻数字,求排成递增序的最少交换次数。
分析:逆序数。排序最少交换次数:1.相邻交换,为逆序数;随意交换,为总数减环个数。
证明:每次相邻交换时,逆序数减1或者加1,所以最优情况下,逆序数为交换次数下界。
存在性,每次找到逆序对交换即可构造出一种下界。
注意:使用long类型即可。
#include <iostream> #include <cstdlib> #include <cstdio> using namespace std; long Data[500005]; long Save[500005]; //利用合并排序求逆序数 long mergesort( int l, int r ) { if ( l < r ) {; long L = mergesort( l, (l+r)/2 ); long R = mergesort( (l+r)/2+1, r ); //合并排序 int ps = l,pe = (l+r)/2,qs = (l+r)/2+1,s = l; while ( ps <= pe || qs <= r ) if ( qs <= r && ( ps > pe || Data[ps] > Data[qs] ) ) { Save[s ++] = Data[qs ++]; L += pe-ps+1L; }else Save[s ++] = Data[ps ++]; for ( int i = l ; i <= r ; ++ i ) Data[i] = Save[i]; return L+R; }else return 0L; } int main() { int n; while ( scanf("%d",&n) && n ) { for ( int i = 0 ; i < n ; ++ i ) scanf("%ld",&Data[i]); printf("%ld\n",mergesort( 0, n-1 )); } return 0; }