HDU 4911 逆序數(shù)對(duì)

Tag: #hdu4911 #逆序數(shù)對(duì)

題目(原題目:HDU 4911)

bobo has a sequence a 1,a 2,…,a n. He is allowed to swap two adjacent(相鄰) numbers for no more than k times.

Find the minimum number of inversions after his swaps.

Note: The number of inversions is the number of pair (i,j) where 1≤i<j≤n and a i>a j.

Input

The input consists of several tests. For each tests:

The first line contains 2 integers n,k (1≤n≤10 5,0≤k≤10 9). The second line contains n integers a 1,a 2,…,a n (0≤a i≤10 9).

Output

For each tests:

A single integer denotes the minimum number of inversions.

Sample Input

3 1
2 2 1
3 0
2 2 1

Sample Output

1
2

? 本題的要點(diǎn)是求一個(gè)數(shù)列的逆序數(shù)(對(duì)),我們先來看一下逆序數(shù)對(duì)的簡單定義:

在一個(gè)排列中,如果一對(duì)數(shù)的前后位置與大小順序相反,即前面的數(shù)大于后面的數(shù),那么它們就稱為一個(gè)逆序。一個(gè)排列中逆序的總數(shù)就稱為這個(gè)排列的逆序數(shù)。

如2431中,21,43,41,31是逆序,逆序數(shù)是4。

? 那么該如何求逆序?qū)?/strong>:

方法如下:

考察每一位,判斷從這一位往后有多少小于該位的,結(jié)果累加,得到最后結(jié)果。

例如,2,4,3,1 先判斷2,之后有1是小于2的,結(jié)果+1,再判斷4,之后3,1都小于4,結(jié)果+2,判斷3時(shí),結(jié)果再+1,最后得到結(jié)果4.

? 很好理解,那么如何使用算法實(shí)現(xiàn):當(dāng)然,我們可以用兩重循環(huán)暴力求解,但是顯而易見O(x2)的復(fù)雜度非常高;更高效的方式有:歸并排序、樹狀數(shù)組、線段樹。

? 本文為了迎合課上學(xué)習(xí)的歸并排序,所以選擇歸并排序算法來解。

? 歸并排序:主要思想是將整個(gè)序列分成兩部分,分別遞歸將這兩部分排好序之后,再和并為一個(gè)有序的序列。

? 在合并的過程中是將兩個(gè)相鄰并且有序的序列合并成一個(gè)有序序列,如以下一個(gè)無序列和分成的兩個(gè)有序序列

Seq: 3  4  5  2  6  8  9

Seq1:3  4  5

Seq2:2  6  8  9

合并成一個(gè)有序列:

Seq*:2  3  4  5  6  8  9

? 對(duì)于序列seq1中的某個(gè)數(shù)a[i],序列seq2中的某個(gè)數(shù)a[j],如果a[i]<a[j],沒有逆序數(shù),如果a[i]>a[j],那么逆序數(shù)為seq1中a[i]后邊元素的個(gè)數(shù)(包括a[i]),即len1-i;

? 這樣累加每次遞歸過程的逆序數(shù),在完成整個(gè)遞歸過程之后,最后的累加和就是逆序的總數(shù)。不難理解。

? 題中還提到只可交換相鄰的數(shù)字,這里引入一個(gè)逆序數(shù)定理

逆序數(shù)定理,當(dāng)逆序?qū)?shù)大于0時(shí),若ak<ak+1,那么交換后逆序?qū)?shù)+1,反之-1。

? 這個(gè)其實(shí)也不難理解。

完整代碼

#include<iostream>
#include<string>

using namespace std;

#define ll long long

ll cnt ;

void Merge(int* A, int p, int q, int r) //根據(jù)算法導(dǎo)論改寫
{
    int n1 = q - p + 1;
    int n2 = r - q;

    int i, j, k;

    int *L = new int[n1 + 1];
    int *R = new int[n2 + 1];

    for(i= 0;i< n1;i++)
    {
        L[i] = A[p + i];
    }
    for(j= 0;j< n2;j++)
    {
        R[j] = A[q + j + 1];
    }

    L[n1] = INT_MAX;//書中的哨兵牌,表示正無窮,這里用INT_MAX來代替。
    R[n2] = INT_MAX;


    for(i= 0,j= 0,k= p;k<= r;k++)
    {
        if (L[i]<=R[j])
        {
            A[k]= L[i];
            i++;
        }
        else //L[i]>R[j]出現(xiàn)逆序
        {
            A[k]= R[j];
            j++;
            cnt += (n1 - i); //根據(jù)逆序數(shù)定理添加的代碼
        }
    }
}

void MergeSort(int* A,int p,int r)
{
    if(p< r)
    {
        int q = (p+ r)/2;
        MergeSort(A,p,q);
        MergeSort(A,q+1,r);
        Merge(A,p,q,r);
    }
}

int main()
{
    /*int n, k, A[1000000];//n<=10^5
    while(cin>>n>>k)
    {
        cnt = 0;
        for(int i =0;i < n;i++)
            cin>>A[i];
        MergeSort(A,0,n-1);
        cnt -= k;
        if(cnt<0) cnt=0;
        cout<<cnt<<endl;
    }*/
//cin和cout效率屬實(shí)差勁
    int n,k;
    int a[10000000];
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        cnt=0;
        for(int i=0;i<n;i++) scanf("%d",&a[i]);
        MergeSort(a,0,n-1);
        printf("%lld\n",max((ll)0,cnt-k));
    }
}

參考文章:

https://blog.csdn.net/crescent__moon/article/details/38424829

https://www.cnblogs.com/neopenx/p/4465348.html

https://blog.csdn.net/acm_jl/article/details/51147010

https://blog.csdn.net/qq_39627843/article/details/81204671

歸并排序算法參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在C語言中,五種基本數(shù)據(jù)類型存儲(chǔ)空間長度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來閱讀 3,993評(píng)論 0 2
  • 概述 排序有內(nèi)部排序和外部排序,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部...
    蟻前閱讀 5,297評(píng)論 0 52
  • 一些概念 數(shù)據(jù)結(jié)構(gòu)就是研究數(shù)據(jù)的邏輯結(jié)構(gòu)和物理結(jié)構(gòu)以及它們之間相互關(guān)系,并對(duì)這種結(jié)構(gòu)定義相應(yīng)的運(yùn)算,而且確保經(jīng)過這...
    Winterfell_Z閱讀 6,573評(píng)論 0 13
  • 1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 將一個(gè)記錄插入到已排序好...
    依依玖玥閱讀 1,347評(píng)論 0 2
  • 夢到我回歸老本行,又去做家教了,我在一家很豪華的房子里,我輔導(dǎo)的那個(gè)孩子去寫作業(yè)咯,然后我又去幫他洗衣服,怎么感覺...
    fangflower閱讀 244評(píng)論 0 0

友情鏈接更多精彩內(nèi)容