zoukankan      html  css  js  c++  java
  • HDU 1394Minimum Inversion Number 数状数组 逆序对数量和

    Minimum Inversion Number

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


    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
     
    Recommend
    Ignatius.L   |   We have carefully selected several similar problems for you:  1166 1698 1540 1542 1255 
     
    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394
    题意:求出对(ai,aj)(i<j,ai>aj)的全部数量。即求ai右边比ai小的数的个数和。每次变换a的序列,求出最小的逆序对数量和。
    思路: 因为树状数组的最基本功能就是求比某点 x 小的点的个数。所以逆向存储ai。
    代码:
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int MAXN=1e6+100,INF=1e9+100;
    int a[MAXN],c[MAXN],ans[MAXN];
    int lowbit(int x)
    {
        return x&(-x);
    }
    void add(int i,int val)
    {
        for(i; i<=MAXN; i+=lowbit(i))
            c[i]+=val;
    }
    int sum(int i)
    {
        int s=0;
        for(i; i>0; i-=lowbit(i))
            s+=c[i];
        return s;
    }
    int main()
    {
        int i,j,t,n;
        while(scanf("%d",&n)!=EOF)
        {
            for(i=n; i>=1; i--)
                scanf("%d",&a[i]);
            memset(c,0,sizeof(c));
            memset(ans,0,sizeof(ans));
            int cou=0;
            for(i=1; i<=n; i++)
            {
                ans[i]=sum(a[i]+1);
                cou+=ans[i];
                add(a[i]+1,1);
            }
            int Min=cou;
            for(i=n; i>1; i--)
            {
                for(j=1; j<=n; j++)
                {
                    if(j==i) continue;
                    if(a[i]<a[j])
                    {
                        cou++;
                        ans[j]++;
                    }
                }
                cou-=ans[i];
                ans[i]=0;
                if(cou<Min) Min=cou;
            }
            cout<<Min<<endl;
        }
        return 0;
    }
    逆序对
    I am a slow walker,but I never walk backwards.
  • 相关阅读:
    bzoj 3527: [Zjoi2014]力
    bzoj 1797: [Ahoi2009]Mincut 最小割
    bzoj 1028: [JSOI2007]麻将
    bzoj 1019: [SHOI2008]汉诺塔
    bzoj 1023: [SHOI2008]cactus仙人掌图
    bzoj 3289: Mato的文件管理
    bzoj 4034: [HAOI2015]T2
    bzoj 1218: [HNOI2003]激光炸弹
    bzoj 2431: [HAOI2009]逆序对数列
    The full stack trace of the root cause is available in the Apache Tomcat/8.0.8 logs.
  • 原文地址:https://www.cnblogs.com/GeekZRF/p/5932079.html
Copyright © 2011-2022 走看看