I'm bored with it ..
In fact, the key to this question is not the method of reverse order, because it is also possible to use brute force.
To give a sequence with the length of n (n <= 5000), from 0 ~ N-1 digits. Each time we move the leftmost number to rightmost to form a new sequence. Then a total of N sequences can be formed. Find the minimum number of reverse orders in the N sequences.
I use array a [0 ~ N-1] to store raw data. You only need to find the sum of the reverse order of the original sequence, and then for each order of a [I] (0 <= I <n-1, use sum to subtract the number (that is, a [I]) of a smaller number on the right side of the object. after sum is used, the number (n-A [I]-1) on the left is shifted to the reverse order of a [I ].
1. Violence Law.
Problem: 1394 (minimum inversion number) Judge Status: Accepted
Runid: 2732590 language: C ++ Author: yueashuxia
Code render status: rendered by hdoj C ++ code render version 0.01 Beta
#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;#define MAX 50001int n,a[MAX];int main (){ int i, j, MIN, sum ; while(scanf("%d", &n) != EOF ) { sum = 0 ; for(i = 0; i < n; i ++) { scanf("%d", &a[i]); for(j = 0; j < i; j ++) { if(a[j] > a[i]) sum ++ ; } } MIN = sum ; for(i = 0; i < n-1; i ++){ sum = sum - a[i] + (n - a[i] - 1) ; if(sum < MIN) MIN = sum ; } printf("%d/n", MIN); } return 0 ;}
2. Tree array method.
Problem: 1394 (minimum inversion number) Judge Status: Accepted
Runid: 2731410 language: C ++ Author: yueashuxia
Code render status: rendered by hdoj C ++ code render version 0.01 Beta#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;#define MAX 50001int c[MAX],n,a[MAX];int getsum(int i){ int res; for(res=0;i>0;i-=i&(-i)) res+=c[i]; return res;}void modify(int i,int m){ for(;i<=MAX;i+=i&(-i)) c[i]+=m;}int main (){ int i, j, MIN, sum ; while(scanf("%d", &n) != EOF ) { memset(c, 0, sizeof(c)) ; sum = 0 ; for(i = 0; i < n; i ++) { scanf("%d", &a[i]); } for(i = n-1; i >= 0; i --) { modify(a[i]+ 1, 1) ; sum += getsum(a[i]) ; } MIN = sum ; for(i = 0; i < n-1; i ++){ sum = sum - a[i] + (n - a[i] - 1) ; if(sum < MIN) MIN = sum ; } printf("%d/n", MIN); } return 0 ;}
3. Line Segment tree method.
Problem: 1394 (minimum inversion number) Judge Status: Accepted
Runid: 2733007 language: C ++ Author: yueashuxia
Code render status: rendered by hdoj C ++ code render version 0.01 Beta#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;const int size = 50001 ;struct xds{ int lson, rson ; int a, b, info ;}tree[size*3] ;int tot, n, a[size] ;void build(int a, int b){ int now = ++tot ; tree[now].a = a ; tree[now].b = b ; tree[now].info = 0 ; if(a == b) { tree[now].lson = tree[now].rson = 0 ; return ; } int mid = (a + b) >> 1 ; tree[now].lson = tot + 1 ; build(a, mid) ; tree[now].rson = tot + 1 ; build(mid + 1, b) ;}void update(int p, int a){ tree[p].info ++ ; if(tree[p].a == tree[p].b) return ; int mid = (tree[p].a + tree[p].b) >> 1 ; if(a <= mid) update(tree[p].lson, a) ; else update(tree[p].rson, a) ;}int query(int p, int a, int b){ if(tree[p].a == a && tree[p].b == b) { return tree[p].info ; } if(tree[p].a == tree[p].b) return tree[p].info; int mid = (tree[p].a + tree[p].b) >> 1 ; if(b <= mid) return query(tree[p].lson, a, b) ; else if(a > mid) return query(tree[p].rson, a, b) ; else return query(tree[p].lson, a, mid) + query(tree[p].rson, mid + 1, b) ;}int main (){ int i, j, MIN, sum ; while(scanf("%d", &n) != EOF ) { sum = tot = 0 ; build(1, n) ; for(i = 0; i < n; i ++) { scanf("%d", &a[i]); sum += query(1, a[i]+2, n) ; update(1, a[i]+ 1) ; } MIN = sum ; for(i = 0; i < n-1; i ++){ sum = sum - a[i] + (n - a[i] - 1) ; if(sum < MIN) MIN = sum ; } printf("%d/n", MIN); } return 0 ;}
4. Merge Sorting.
Problem : 1394 ( Minimum Inversion Number ) Judge Status : AcceptedRunId : 2732771 Language : C++ Author : yueashuxiaCode Render Status : Rendered By HDOJ C++ Code Render Version 0.01 Beta
# Include <stdio. h> # include <string. h >#include <iostream >#include <algorithm> using namespace STD; # define Max 50001 typedef int t; t num [Max], a [Max], sum, B [Max]; // sorts the num array in ascending order. A is the auxiliary array void mergesort (T left, t mid, t right) {t I = left, j = Mid + 1, K = 0; while (I <= Mid & J <= right) {If (Num [I] <= num [J]) A [k ++] = num [I ++]; else {sum + = mid-I + 1; // if this sentence is added and sum = 0 is initialized, the sum is the reverse number of the original sequence. A [k ++] = num [J ++];} while (I <= mid) A [k ++] = num [I + +]; While (j <= right) A [k ++] = num [J ++]; for (I = left, j = 0; I <= right; I ++) num [I] = A [J ++];} void Merge (T left, t right) {// grouping if (left <right) {Merge (left, (left + right)/2); merge (left + right)/2 + 1, right); mergesort (left, (left + right) /2, right) ;}} int main () {int N, I, j, Min, last; while (scanf ("% d", & N )! = EOF) {for (I = 0; I <n; I ++) {scanf ("% d", & num [I]); B [I] = num [I];} sum = 0; merge (0, n-1); min = sum; for (I = 0; I <n-1; I ++) {sum = sum-B [I] + (n-B [I]-1); If (sum <min) min = sum ;} printf ("% d/N", min);} return 0 ;}