C-Minimum inversion number
Time Limit: 1000 ms memory limit: 32768kb 64bit Io format: % i64d & % i64u
Submit
Status
Description
The inversion number of a given number sequence
A1, A2,..., an is the number of pairs (AI, AJ)
That satisfy I <j and AI> AJ.
For a given sequence of numbers A1, A2,...,,
If we move the first m> = 0 numbers to the end of the seqence,
We will obtain another sequence.
There are totally N such sequences as the following:
A1, A2,..., An-1, an (where m = 0-the initial seqence)
A2, A3,..., An, A1 (where M = 1)
A3, A4,..., An, A1, A2 (where m = 2)
...
An, A1, A2,..., An-1 (where M = N-1)
You are asked to write a program
To find the minimum inversion number out of the above sequences.
Input
The input consists of a number of test cases.
Each case consists of two lines:
The first line contains a positive integer n (n <= 5000 );
The next line contains a permutation of the N integers from 0 to n-1.
Output
For each case,
Output The minimum inversion number on a single line.
Sample Input
10
1 3 6 9 0 8 5 7 4 2
Sample output
16
The question implies that N numbers from 0 to N can be arranged in a given order. Each time, only the first number can be moved to the end to calculate the reverse number of each case and obtain the minimum value of the reverse number.
This question is an application of Merge Sorting.
First, we can find the number of reverse orders in the current situation.
Then round n times, the first one moves to the last one, then ans = ans + (n-1 + A [I])-A [I]
#include<stdio.h>#include<string.h>#include<math.h>#include<iostream>#include<algorithm>#include<queue>#include<stack>#define mem(a,b) memset(a,b,sizeof(a))#define ll __int64#define MAXN 1000#define INF 0x7ffffff#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;int num[ 5000+10],a[5000+10];int vis[5000+10];int ans;void Merge(int begin,int mid,int end){ int i=begin,j=mid+1,k=begin; while(i<=mid&&j<=end) { if(a[i]<=a[j]) vis[k++]=a[i++]; else { ans+=mid-i+1; vis[k++]=a[j++]; } } while(i<=mid) { vis[k++]=a[i++]; } while(j<=end) { vis[k++]=a[j++]; } for(i=begin;i<=end;i++) { a[i]=vis[i]; }}void mergesort(int begin,int end){ if(begin!=end) { int mid=(begin+end)/2; mergesort(begin,mid); mergesort(mid+1,end); Merge(begin,mid,end); }}int main(){ int n,i,j,minn; while(scanf("%d",&n)!=EOF) { ans=0; for(i=1;i<=n;i++) {scanf("%d",&a[i]); num[i]=a[i];} mergesort(1,n); minn=ans; for(i=1;i<n;i++) { ans=ans+n-1-2*num[i]; if(ans<minn) minn=ans; } cout<<minn<<endl; } return 0;}