hdu1394 Minimum Inversion Number

Minimum Inversion Number

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 15538    Accepted Submission(s): 9479


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.
 

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
ZOJ Monthly, January 2003 
 

Recommend
Ignatius.L   |   We have carefully selected several similar problems for you:   1166  1698  1540  1542  1255 
 




树状数组求逆序对。

每次将一个点从最前面移动到最后面,只需要将当前的逆序对数加上比它大的数的个数,再减去比它小的数的个数。




#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define LL long long
#define pa pair<int,int>
#define MAXN 5005
#define INF 1000000000
using namespace std;
int a[MAXN],f[MAXN],ans,now,n;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
inline int getsum(int x)
{
	int ret=0;
	for(int i=x;i;i-=(-i)&i) ret+=f[i];
	return ret;
}
inline void add(int x)
{
	for(int i=x;i<=n;i+=(-i)&i) f[i]++;
}
int main()
{
	while (~scanf("%d",&n))
	{
		now=0;
		memset(f,0,sizeof(f));
		F(i,1,n) a[i]=read()+1;
		D(i,n,1){now+=getsum(a[i]-1);add(a[i]);}
		ans=now;
		F(i,1,n-1) now=now+n+1-a[i]*2,ans=min(ans,now);
		printf("%d\n",ans);
	}
}


你可能感兴趣的:(HDU)