HDU 1394 - Minimum Inversion Number

求环上的逆序对最小值,这题据说应该是用线段树去做,我先拍了一个裸的,总复杂度O(N2):

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 #define MAXN    5000
 6 
 7 int N;
 8 int A[MAXN], sorted[MAXN];
 9 
10 int bisrch(int v)
11 {
12     int l, r;
13     l = 0, r = N-1;
14     while(l<r) {
15         int m = (l+r) >> 1;
16         if (v > sorted[m]) l = m+1;
17         else if (v < sorted[m]) r = m-1;
18         else return m;
19     }
20     return l;
21 }
22 
23 int main(void)
24 {
25     while(scanf("%d", &N) > 0) {
26         for(int i=0; i<N; ++i) {
27             scanf("%d", &A[i]);
28             sorted[i] = A[i];
29         }
30         int invpairs = 0;
31         for(int i=0; i<N-1; ++i) {
32             int k = i;
33             for(int j=i+1; j<N; ++j) {
34                 invpairs += (A[j] < A[i]);
35                 if (sorted[j] < sorted[k]) k = j;
36             }
37             swap(sorted[i], sorted[k]);
38         }
39         int mininv = invpairs;
40         for(int i=0; i<N; ++i) {
41             int j = bisrch(A[i]);
42             invpairs += N-(j<<1) - 1;
43             if (mininv > invpairs) mininv = invpairs;
44         }
45         printf("%d\n", mininv);
46     }
47     return 0;
48 }

 

2014-06-04 00:05:31 Accepted 1394 234MS 220K 867 B G++

 

6/4 线段树解法:其实本题能用线段树的原因是因为该序列是0~N-1的一个排列(隐含的意思是期间每个数都会包含)【比我第一眼认为的问题还要特殊】。
因为值的区间在[0,N-1]上,所以可以用线段树进行动态统计,具体的代码再写吧。

posted @ 2014-06-04 00:20  e0e1e  阅读(117)  评论(0编辑  收藏  举报