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. 

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 }

 

posted @ 2016-09-13 17:44  SilverNebula  阅读(271)  评论(0编辑  收藏  举报
AmazingCounters.com