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]上,所以可以用线段树进行动态统计,具体的代码再写吧。
This article is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
本文采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。