HDU1394 Minimum Inversion Number

  原题传送:http://acm.hdu.edu.cn/showproblem.php?pid=1394

  求逆序数。

  题目上来一看,发现直接暴力可过,复杂度O(n2),300+ms,代码简短得要命:

View Code
 1 #include <stdio.h>
 2 
 3 int a[5005];
 4 
 5 inline int min(int x, int y)
 6 {
 7     return x < y ? x : y;
 8 }
 9 
10 int main()
11 {
12     int i, j, n, ans, m;
13     while(scanf("%d", &n) != EOF)
14     {
15         ans = 0;
16         for(i = 1; i <= n; i ++)
17             scanf("%d", &a[i]);
18             
19         for(i = 1; i <= n; i ++)
20             for(j = i + 1; j <= n; j ++)
21                 if(a[i] > a[j])
22                     ans ++;
23         m = ans;
24         for(i = 1; i < n; i ++)
25             ans = min(ans, m = m + n - a[i] - 1 - a[i]);
26         printf("%d\n", ans);
27     }
28     return 0;
29 }

 

  其实这道题复杂度都耗在了第一次求总逆序数上了,后来想想,发现可以用nlog(n)的归并排序搞,15~30ms。

View Code
 1 #include <stdio.h>
 2 #define N 5005
 3 int a[N], b[N], c[N];
 4 
 5 inline int min(int x, int y)
 6 {
 7     return x < y ? x : y;
 8 }
 9 
10 int cal(int s, int t)
11 {
12     int i, j, k, mid;
13     int res;
14     if(t - s == 1)
15         return 0;
16     mid = (s + t) >> 1;
17     res = cal(s, mid) + cal(mid, t);
18     i = s, j = mid, k = s;
19     while(i < mid && j < t)
20     {
21         if(a[i] <= a[j])
22             b[k ++] = a[i ++], res += j - mid;
23         else
24             b[k ++] = a[j ++];
25     }
26     while(i < mid) b[k ++] = a[i ++], res += j - mid;
27     while(j < t) b[k ++] = a[j ++];
28     for(i = 0; i < t - s; i ++)
29         a[s + i]= b[s + i];
30     return res;
31 }
32 
33 int main()
34 {
35     int i, n, ans, m;
36     while(scanf("%d", &n) != EOF)
37     {
38         for(i = 1; i <= n; i ++)
39         {
40             scanf("%d", &a[i]);
41             c[i] = a[i];
42         }
43         ans = cal(1, n + 1);
44         m = ans;
45         for(i = 1; i < n; i ++)
46             ans = min(ans, m = m + n - c[i] - 1 - c[i]);
47         printf("%d\n", ans);
48     }
49     return 0;
50 }

 

  其实我是想用线段树写的,30ms。

View Code
 1 #include <stdio.h>
 2 #include <string.h>
 3 #define lson (cur << 1)
 4 #define rson (cur << 1 | 1)
 5 #define N 5005
 6 
 7 int tree[N << 2], a[N];
 8 
 9 inline int min(int x, int y)
10 {
11     return x < y ? x : y;
12 }
13 
14 void pushup(int cur)
15 {
16     tree[cur] = tree[lson] + tree[rson];
17 }
18 
19 void query(int cur, int l, int r, int x, int y, int &ans)
20 {
21     if(l >= x && r <= y)
22     {
23         ans += tree[cur];
24         return ;
25     }
26     int mid = (l + r) >> 1;
27     if(mid >= x)
28         query(lson, l, mid, x, y, ans);
29     if(mid + 1 <= y)
30         query(rson, mid + 1, r, x, y, ans);
31 }
32 
33 void update(int cur, int l, int r, int loc)
34 {
35     if(l == r)
36     {
37         tree[cur] = 1;
38         return ;
39     }
40     int mid = (l + r) >> 1;
41     if(mid >= loc)
42         update(lson, l, mid, loc);
43     else
44         update(rson, mid + 1, r, loc);
45     pushup(cur);
46 }
47 
48 int main()
49 {
50     int n, i, v, ans, sum;
51     while(scanf("%d", &n) != EOF)
52     {
53         memset(tree, 0, sizeof tree);
54         for(sum = 0, i = 1; i <= n; i ++)
55         {
56             scanf("%d", &a[i]);
57             v = 0;
58             query(1, 1, n, a[i] + 1, n, v);
59             sum += v;
60             update(1, 1, n, a[i]);
61         }
62         ans = sum;
63         for(i = 1; i < n; i ++)
64             ans = min(ans, sum = sum + n - a[i] - 1 - a[i]);
65         printf("%d\n", ans);
66     }
67     return 0;
68 }
posted @ 2012-09-24 21:05  芒果布丁  阅读(141)  评论(0编辑  收藏  举报