hdu 1394 解題報告 Minimum Inversion Number

來源:互聯網
上載者:User
Minimum Inversion Number

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


Problem DescriptionThe 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. 


InputThe 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. 


OutputFor each case, output the minimum inversion number on a single line. 


Sample Input

101 3 6 9 0 8 5 7 4 2
 


Sample Output

16又是一個經典的線段樹,首先要知道如何求一個序列的逆序——比如2514 : 2之前沒有數大於它,所以為0, 5之前也沒有數大於它,所以為0, 1之前2,5都大於它,所以為2, 4之前只有5大於它,所以為1, 因此2514的逆序數為:0  + 0 + 2 + 1 = 3; 從前面的描述中,我們可以發現,只要依次累計前面有幾個數大於當前數即可。於是我們可以用一個數組l[n](初始化為0),然後每讀取一個數x[i] 就標識l[x[i]] += 1 , 但是在標識之前我們先要統計有多少個數大於x[i],即累計l[x[i]+1] + ... +l[n-1],很顯然累計的時間複雜度為O(N),我們能不能在快點呢?  那麼如何求最小逆序數呢?(我這裡假設一個序列中每個數字都不同) 若abcde...的逆序數為sum,那麼bcde...a的逆序數是多少?我們假設abcde...中小於a的個數為x[i] , 那麼大於a的個數就是n - x[i],當把a移動左移一位時,原來比a大的現在都成了a的逆序對,故減少了x[i]+1,即 相比而言總共加了n-x[i]-x[i]-1;其實,線段樹只有開始用了一次,後面求最小值就沒用了,所以用暴力應該也能過,sum再更新N—-1次就可以得到最小值了,不算複雜!

於是我

#include <iostream>#include<stdio.h>using namespace std;#define N 50000int l[N<<2],x[N];void build(int num ,int s,int e){      l[num]=0;      if(s==e)            return ;      int mid=(s+e)>>1;      build(num<<1,s,mid);      build(num<<1|1,mid+1,e);}int query(int num ,int s,int e ,int a,int b){      if(a<=s&&b>=e)            return l[num];      int mid=(s+e)>>1;      int ret=0;      if(mid>=a)            ret+=query(num<<1,s,mid,a,b);      if(mid<b)            ret+=query(num<<1|1,mid+1,e,a,b);      return ret;}void update(int num ,int s,int e,int a){      if(s==e)      {           l[num]++;           return ;      }      int mid=(s+e)>>1;      if(a<=mid)            update(num<<1,s,mid,a);      else            update(num<<1|1,mid+1,e,a);      l[num]=l[num<<1]+l[num<<1|1];}int main(){    int n,i;    while(scanf("%d",&n)!=EOF)    {          build(1,0,n-1);          int sum=0;         for(i=0;i<n;i++)         {               scanf("%d",&x[i]);               sum=sum+query(1,0,n-1,x[i],n-1);               update(1,0,n-1,x[i]);         }         int re=sum;         for(i=0;i<n-1;i++)         {               sum+=n-x[i]-x[i]-1;               if(sum<re)                  re=sum;         }         printf("%d\n",re);    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.