HDU1394 Minimum Inversion Number
Time Limit: 1000MS | Memory Limit: 32768KB | 64bit IO Format: %I64d & %I64u |
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
Source
在环上找一个起点,使得从该起点数起的长度为n的链中逆序对数最小。
破环为链会T。
正解是每次将链头的数移到尾部,用公式计算出逆序对的变化量。
WA了三次才看到题目包含多组数据,WA的一声就哭了
1 /*by SilverN*/ 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 using namespace std; 8 const int mxn=12000; 9 int t[mxn]; 10 int n; 11 int read(){ 12 int x=0,f=1;char ch=getchar(); 13 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 14 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 15 return x; 16 } 17 int lowbit(int x){ 18 return x&-x; 19 } 20 void add(int pos,int v){ 21 while(pos<=n){ 22 t[pos]+=v; 23 pos+=lowbit(pos); 24 } 25 return; 26 } 27 int ask(int x){ 28 int res=0; 29 while(x){ 30 res+=t[x]; 31 x-=lowbit(x); 32 } 33 return res; 34 } 35 int ans=1e8; 36 int a[mxn]; 37 int main(){ 38 while(scanf("%d",&n)!=EOF){ 39 memset(t,0,sizeof t); 40 ans=1e8; 41 int i,j; 42 int res=0; 43 for(i=1;i<=n;i++){ 44 a[i]=read(); 45 a[i]++; 46 res+=ask(n)-ask(a[i]); 47 add(a[i],1); 48 } 49 ans=min(ans,res); 50 for(i=1;i<=n;i++){ 51 res+=(n-a[i])-(a[i]-1); 52 ans=min(ans,res); 53 } 54 printf("%d\n",ans); 55 } 56 return 0; 57 }
本文为博主原创文章,转载请注明出处。