【HDOJ】1394 Minimum Inversion Number

逆序数的性质。
1. 暴力解

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

2. 线段树。需要理解如何求逆序数。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 #define lson l, m, rt<<1
 7 #define rson m+1, r, rt<<1|1
 8 
 9 const int maxn = 5005;
10 
11 int nums[maxn<<2];
12 int a[maxn];
13 
14 void PushUP(int rt) {
15     nums[rt] = nums[rt<<1] + nums[rt<<1|1];
16 }
17 
18 void build(int l, int r, int rt) {
19     nums[rt] = 0;
20     if (l == r) return;
21     int m = (l+r)>>1;
22     build(lson);
23     build(rson);
24 }
25 
26 void update(int p, int l, int r, int rt) {
27     if (l == r) {
28         nums[rt] = 1;
29         return ;
30     }
31     int m = (l+r)>>1;
32     if (p <= m)
33         update(p, lson);
34     else
35         update(p, rson);
36     PushUP(rt);
37 }
38 
39 int query(int ll, int rr, int l, int r, int rt) {
40     if (ll<=l && rr>=r) {
41         return nums[rt];
42     }
43     int m = (l+r)>>1;
44     int ret = 0;
45     if (ll <= m)
46         ret += query(ll, rr, lson);
47     if (rr > m)
48         ret += query(ll, rr, rson);
49 
50     return ret;
51 }
52 
53 int main() {
54     int n;
55     int i, sum, min;
56 
57     while (scanf("%d", &n) != EOF) {
58         build(0, n-1, 1);
59         sum = 0;
60         for (i=0; i<n; ++i) {
61             scanf("%d", &a[i]);
62             sum += query(a[i], n-1, 0, n-1, 1);
63             update(a[i], 0, n-1, 1);
64             //printf("%d: sum=%d
", i, sum);
65         }
66         min = sum;
67         for (i=0; i<n; ++i) {
68             sum += n - 1 - a[i]*2;
69             if (sum < min)
70                 min = sum;
71         }
72         printf("%d
", min);
73     }
74 
75     return 0;
76 }
原文地址:https://www.cnblogs.com/bombe1013/p/3761381.html