hdu-1394 Minimum Inversion Number---树状数组

题目链接:

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 }

猜你喜欢

转载自www.cnblogs.com/fzl194/p/8964541.html