zoukankan      html  css  js  c++  java
  • 逆序数的求法

    求一个数列的逆序数

    逆序对:数列s[1],a[2],a[3]…中的任意两个数s[i],s[j] (i<j),如果s[i]>s[j],那么我们就说这两个数构成了一个逆序对

    逆序数:一个数列中逆序对的总数

    如数列 3 5 4 8 2 6 9

    (5,4)是一个逆序对,同样还有(3,2),(5,2),(4,2)等等

    那么如何求得一个数列的逆序数呢?

    方法1:一个一个的数

    最简单也是最容易想到的方法就是,对于数列中的每一个数s[i],遍历数列中的数s[j](其中j<i),若s[i]<s[j],则逆序数加1,这样就能统计出该数列的逆序数总和

    该方法的时间复杂度为O(n2),具体过程就不细说了

    代码如下:(POJ  1804 Brainman)

    http://poj.org/problem?id=1804

    /*直接求逆序数O(n^2)*/
    
    //Memory Time 
    //220K  188MS
    
    #include <iostream>    
    using namespace std;
    
    int main(int i,int j)
    {
        int test;
        cin>>test;
        for(int p=1;p<=test;p++)
        {
            int n;
            cin>>n;
    
            int* s=new int[n+1];
            for(i=1;i<=n;i++)
                cin>>s[i];
    
            int t=0;  //s[]的逆序数
            for(i=1;i<=n-1;i++)   //把S[i]和s[i+1~n]的元素逐个比较
                for(j=i+1;j<=n;j++)
                    if(s[i]>s[j])  //如果s[i] > s[j] (j∈[i+1,n]) 
                        t++;   //则逆序数t++
    
            cout<<"Scenario #"<<p<<':'<<endl<<t<<endl<<endl;
    
            delete s;
        } 
        return 0;
    }

    方法2:归并的思想

    有一种排序的方法是归并排序,归并排序的主要思想是将整个序列分成两部分,分别递归将这两部分排好序之后,再和并为一个有序的序列.复杂度为O(nlogn)算法

    /*借助Mergesort求逆序数O(nlogn)*/
    
    //Memory Time 
    //228K   172MS 
    
    #include<iostream>
    using namespace std;
    
    const int inf=1000001;
    int t;  //数字序列s[]的逆序数
    
    void compute_t(int* s,int top,int mid,int end)
    {
        int len1=mid-top+1;
        int len2=end-mid;
    
        int* left=new int[len1+2];
        int* right=new int[len2+2];
    
        int i,j;
        for(i=1;i<=len1;i++)
            left[i]=s[top+i-1];
        left[len1+1]=inf;
    
        for(j=1;j<=len2;j++)
            right[j]=s[mid+j];
        right[len2+1]=inf;
    
        i=j=1;
        for(int k=top;k<=end;k++)
            if(left[i]<=right[j])
                s[k]=left[i++];
            else
            {
                s[k]=right[j++];
                t+=len1-i+1;
            }
    
        delete left;
        delete right;
    
        return;
    }
    
    void mergesort(int* s,int top,int end)
    {
        if(top<end)
        {
            int mid=(top+end)/2;
            mergesort(s,top,mid);
            mergesort(s,mid+1,end);
            compute_t(s,top,mid,end);
        }
        return;
    }
    int main(void)
    {
        int test;
        cin>>test;
        for(int p=1;p<=test;p++)
        {
            int n;  //数字序列s[]长度
            cin>>n;
    
            int* s=new int[n+1];
    
            for(int i=1;i<=n;i++)
                cin>>s[i];
    
            t=0;
            mergesort(s,1,n);
    
            cout<<"Scenario #"<<p<<':'<<endl<<t<<endl<<endl;
    
            delete s;
        }
        return 0;
    }
  • 相关阅读:
    mysql远程访问设置
    LUA Userdata
    LUA 面向对象
    LUA table中函数的调用
    LUA 元表
    LUA table
    hibernate3 和hibernate4的一点小变动
    java 关键字final
    MySQL oracle 分页
    Java后端开发书架
  • 原文地址:https://www.cnblogs.com/wft1990/p/6040941.html
Copyright © 2011-2022 走看看