• HDU 1394 Minimum Inversion Number (线段树,暴力)


    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
     
          这题就是求逆序数题,给你一个数列,找出它的逆序数,然后通过以上变换分别求出变换后的逆序数,输出最小值就是答案了。
          假设ans是初始逆序数,那么他的下一个数列的逆序数ans1=ans+n-2*a[0]-1;因为把a[0]移到后面逆序数就要减少a[0],也要加上n-a[0]-1;如果这看懂了,这题就不难了,数据不大,求逆序数用线段树,暴力什么都能解决。
     
      暴力:
     
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int main()
    {
        int n,a[100000],i,j,ans1,ans2;
        while (~scanf("%d",&n))
        {
            ans1=0;
            for (i=0;i<n;i++) scanf("%d",&a[i]);
            for (i=1;i<n;i++)
            for (j=0;j<i;j++)
            if (a[i]<a[j]) ans1++;
            ans2=ans1;
            for (i=0;i<n;i++)
            {
                ans1=ans1+n-2*a[i]-1;
                ans2=min(ans1,ans2);
            }
            printf("%d
    ",ans2);
        }
        return 0;
    }
    

      

         线段树

        

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int s[50000];
    struct p
    {
        int x,y,su;
    };p tree[1000000];
    void build(int l,int r,int p)
    {
        tree[p].x=l;
        tree[p].y=r;
        tree[p].su=0;
        if (l==r) return ;
        int m=(l+r)/2;
        build(l,m,2*p);
        build(m+1,r,2*p+1);
        return ;
    }
    int find(int l,int r,int p)
    {
        if (tree[p].x==l&&tree[p].y==r) return tree[p].su;
        int m=(tree[p].x+tree[p].y)/2;
        if (l>m) return find(l,r,2*p+1);
        if (m>=r) return find(l,r,2*p);
        return find(l,m,2*p)+find(m+1,r,2*p+1);
    }
    void un(int pos,int i,int p)
    {
        tree[p].su+=i;
        if (tree[p].x==tree[p].y) return ;
        int m=(tree[p].x+tree[p].y)/2;
        if (pos<=m) un(pos,i,2*p);
        else un(pos,i,2*p+1);
    }
    int main()
    {
        int n,i,ans,mn;
        while (~scanf("%d",&n))
        {
            build(0,n-1,1);
            ans=0;
            for (i=0;i<n;i++) scanf("%d",&s[i]);
            for (i=0;i<n;i++)
            {
                ans+=find(s[i],n-1,1);
                un(s[i],1,1);
            }
            mn=ans;
            for (i=0;i<n;i++)
            {
                ans=ans+n-2*s[i]-1;
                mn=min(mn,ans);
    
            }
            printf("%d
    ",mn);
        }
        return 0;
    }
    

      

     
  • 相关阅读:
    windows 系列机器查看tcp 配置
    test windows live writer
    win7 mysql 启动 问题
    用enum枚举量做下标初始化数组
    二层VXLAN静态配置
    pip install scrapy报错原文
    python练习2
    pycharm字体大小设置快捷键的方法
    python练习1
    centos 7下修改IP地址为静态
  • 原文地址:https://www.cnblogs.com/pblr/p/4721321.html
Copyright © 2020-2023  润新知