FZOJ 2166 inversion

算是一道模擬題吧,,,此題就逆序數不用歸併排序之類的,而是用雙層for循環模擬求解,,因爲題意中要求任意兩個數交換位置,所以只需在雙層for循環中模擬兩個數交換即可,在模擬的過程中,不需要準確的求出模擬之後的逆序數,只需要考慮逆序數的變化量爲多少,最後,求出變化量最小的,用最初的逆序數求得最後結果。。。

其中模擬兩個數交換之後逆序數的變化量解法:

如下:

  a,b,c,d,e,f,g,h,i,g,k,l,m.....;   一系列數。

假設我們求交換   d    和    l     的數,其逆序數的變化量。

數列將變爲:

  a,b,c,l,e,f,g,h,i,g,k,d,m.....; 

我們先看,在   d    到     l      這一段數中,有多少個比    d     大的數,記爲  cnt1   ,那麼,將    d    交換之後, 這  cnt1  個數將會各增加1個比其本身小的數,則最終總的逆序數則加  cnt1  ;

我們在看,有多少個比    d    小的數,記爲  cnt2 ,  則   相對於   d   來說,最後少了  cnt2  個比    d    小的數, 則最後結果減  cnt2;

同理   對  l   進行一次與   d    相同的操作,則最後的結果變化量則爲交換   d     與   l    的逆序數的變化量。


代碼如下:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<math.h>
#include<algorithm>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<string>
#include<vector>
#define INF 0x7fffffff
using namespace std;
int num[1002];
int z[1002][1002];//統計逆序數的變化量。
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        memset(z,0,sizeof(z));
        for(int i=0; i<n; i++)
        {
            scanf("%d",&num[i]);
        }
        int res=0;//求最初的逆序數
        for(int i=0; i<n; i++)
        {
            int cnt=0;
            for(int j=i+1; j<n; j++)
            {
                if(num[j]<num[i])
                {
                    res++;//總的逆序數
                    cnt--;
                }
                else if(num[j]>num[i])
                    cnt++;
                z[i][j]=cnt;//統計與第一個交換數比較後的逆序數變化量
            }
        }
        for(int i=n-1; i>0; i--)
        {
            int cnt=0;
            for(int j=i-1; j>0; j--)
            {
                if(num[j]<num[i])
                    cnt++;
                else if(num[j]>num[i])
                    cnt--;
                z[j-1][i]+=cnt;//加上與第二個交換數比較後的逆序數變化量
            }
        }
        int m=0;//找到逆序數最小的變化量
        for(int i=0; i<n; i++)
            for(int j=i+1; j<n; j++)
                m=m>z[i][j]?z[i][j]:m;
        printf("%d\n",res+m);
    }
}

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章