Minimum Inversion Number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 13036 Accepted Submission(s): 7968
Problem 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, ..., an, 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.
For a given sequence of numbers a1, a2, ..., an, 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
Author
CHEN, Gaoli
Source
题目意思:
给一个n,然后一个长度为n的数组,每个元素小于n且不重复,每次操作把首位元素放到末尾,求n次操作中最小的逆序对数目。
思路:
先求一下原始数组的逆序对数目,每次把首位放末尾的时候,num(逆序对数目)加上大于a[i]的,然后减去小于a[i]的。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #include <vector> 6 #include <queue> 7 #include <cmath> 8 #include <set> 9 using namespace std; 10 11 #define N 5005 12 #define ll root<<1 13 #define rr root<<1|1 14 #define mid (a[root].l+a[root].r)/2 15 16 17 int max(int x,int y){return x>y?x:y;} 18 int min(int x,int y){return x<y?x:y;} 19 int abs(int x,int y){return x<0?-x:x;} 20 21 int n; 22 int b[N]; 23 int a[N]; 24 25 int lowbit(int x){ 26 return x&(-x); 27 } 28 29 void solve(int val,int x){ 30 while(x<=n){ 31 a[x]+=val; 32 x+=lowbit(x); 33 } 34 } 35 36 int sum(int x){ 37 int ans=0; 38 while(x>0){ 39 ans+=a[x]; 40 x-=lowbit(x); 41 } 42 return ans; 43 } 44 45 main() 46 { 47 int t, i, j, k; 48 while(scanf("%d",&n)==1){ 49 memset(a,0,sizeof(a)); 50 int ans=0; 51 for(i=1;i<=n;i++) { 52 scanf("%d",&b[i]); 53 b[i]++; 54 ans+=sum(n)-sum(b[i]); 55 solve(1,b[i]); 56 } 57 int num=ans; 58 for(i=1;i<=n;i++){ 59 num+=n-b[i]-b[i]+1;//sum(n)-sum(b[i])-sum(b[i]-1); 60 ans=min(ans,num); 61 } 62 printf("%d ",ans); 63 } 64 }