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 }

 

posted @ 2016-04-04 13:50  Recoder  阅读(297)  评论(0编辑  收藏  举报