HDU 1394 Minimum Inversion Number (树状数组求逆序对)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394
题目让你求一个数组,这个数组可以不断把最前面的元素移到最后,让你求其中某个数组中的逆序对最小是多少。
一开始就求原来初始数组的逆序对,树状数组求或者归并方法求(可以看《挑战程序设计》P178),然后根据最前面的元素大小递推一下每次移到最后得到的逆序数,取最小值。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int MAXN = 5005; 6 int bit[MAXN] , n , a[MAXN]; 7 8 inline void add(int i , int num) { 9 for( ; i <= n ; i += (i & -i)) 10 bit[i] += num; 11 } 12 13 int sum(int i) { 14 int res = 0; 15 for( ; i > 0 ; i -= (i & -i)) 16 res += bit[i]; 17 return res; 18 } 19 20 int main() 21 { 22 while(~scanf("%d" , &n)) { 23 memset(bit , 0 , sizeof(bit)); 24 int res = 0 , ans; 25 for(int i = 0 ; i < n ; i++) { 26 scanf("%d" , a + i); 27 a[i]++; 28 res += i - sum(a[i]); 29 add(a[i] , 1); 30 } 31 ans = res; 32 for(int i = 0 ; i < n - 1 ; i++) { 33 ans -= (a[i] - 1); 34 ans += (n - a[i]); 35 res = min(res , ans); 36 } 37 printf("%d\n" , res); 38 } 39 }