• Minimum Inversion Number


    Minimum Inversion Number
    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 14585 Accepted Submission(s): 8901

    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
    线段树求逆序数,每当你将开头的a[i],移到尾部的时候,逆序数会减少a[i],也会增加n-a[i]-1,所以变化为n-2*a[i]-1,求最小值

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <queue>
    #include <algorithm>
    #define LL long long
    using namespace std;
    
    const int MAX = 5500;
    
    int Tree[MAX*4];
    
    int a[MAX];
    
    int MM;
    
    int Query(int L,int R,int site,int l,int r)
    {
        if(l==L&&R==r)
        {
            return Tree[site];
        }
        int mid=(L+R)>>1;
        if(r<=mid)
        {
            return Query(L,mid,site<<1,l,r);
        }
        else if(l>mid)
        {
            return Query(mid+1,R,site<<1|1,l,r);
        }
        else
        {
            return Query(L,mid,site<<1,l,mid)+Query(mid+1,R,site<<1|1,mid+1,r);
        }
    }
    
    void update(int L,int R,int site,int s)
    {
        if(L==R)
        {
            Tree[site]++;
            return ;
        }
        Tree[site]++;
        int mid = (L+R)>>1;
        if(mid>=s)
        {
            update(L,mid,site<<1,s);
        }
        else
        {
            update(mid+1,R,site<<1|1,s);
        }
    }
    
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            memset(Tree,0,sizeof(Tree));
            int ans=0;
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);//求逆序数
                ans+=Query(0,n-1,1,a[i],n-1);
                update(0,n-1,1,a[i]);
            }
            MM = ans;
            for(int i=1;i<=n;i++)//进行移位
            {
                ans=ans+n-2*a[i]-1;
                if(ans<MM)
                {
                    MM=ans;
                }
            }
            printf("%d
    ",MM);
        }
        return 0;
    }
    
  • 相关阅读:
    bzoj 3438: 小M的作物
    bzoj 4445 [SCOI2015] 小凸想跑步
    hdu 4899 Hero meet devil
    hdu 4898 The Revenge of the Princess’ Knight
    【NOIP1999】拦截导弹
    【OpenJudge】2991:2011 题解
    【cqbzoj】1785:残缺棋盘上放车的方案数 --状压dp --输入毁一生
    【cqbzoj】:1330 Prime DP(Ahio2001 质数和分解)
    【Openjudge:Noi】7891:一元三次方程求解 c++
    【USACO FEB 2010 SILVER】吃巧克力(Chocolate Eating)
  • 原文地址:https://www.cnblogs.com/juechen/p/5255991.html
Copyright © 2020-2023  润新知