题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1394
题目大意:
一个由0..n-1组成的序列,每次可以把队首的元素移到队尾,
求形成的n个序列中最小逆序对数目
解题思路:
如果求出第一种情况的逆序列,其他的可以通过递推来搞出来,一开始是t[1],t[2],t[3]....t[N]
它的逆序列个数是N个,如果把t[1]放到t[N]后面,逆序列个数会减少t[1]个,相应会增加N-(t[1]+1)个
1 #include<bits/stdc++.h> 2 #define lowbit(i) (i & (-i)) 3 using namespace std; 4 const int maxn = 5005; 5 int a[maxn]; 6 int tree[maxn], n; 7 void add(int x, int d) 8 { 9 while(x <= n) 10 tree[x] += d, x += lowbit(x); 11 } 12 int sum(int x) 13 { 14 int ans = 0; 15 while(x) 16 ans += tree[x], x -= lowbit(x); 17 return ans; 18 } 19 int main() 20 { 21 while(cin >> n) 22 { 23 memset(tree, 0, sizeof(tree)); 24 for(int i = 0; i < n; i++) 25 cin >> a[i], a[i]++; 26 int s = 0; 27 for(int i = 0; i < n; i++) 28 { 29 s += i - sum(a[i]); 30 add(a[i], 1); 31 } 32 int ans = s; 33 //cout<<ans<<endl; 34 for(int i = 0; i < n; i++) 35 { 36 s = s + n - 2 * a[i] + 1; 37 ans = min(ans, s); 38 //cout<<ans<<" "<<s<<endl; 39 } 40 cout<<ans<<endl; 41 } 42 return 0; 43 }