P1338 末日的傳說

2022-06-23 12:33:10 字數 2172 閱讀 8231

首先審題,題目中提到    每次它都生成乙個以前未出現過的「最小」的排列。其實這句話的意思就是說,我這個日期每天都會變化,每次變化後的排列都是以前沒出現過的,也就是不會有重複的排列,然後這個日期還是除了以前出現過的排列之外的最小的排列,也就是說啊,我這個日期是按照一定規律來變化的,第一天是字典序最小,第二天是字典序第二小,,,就這樣一直排列,最後一天就是字典序最大,也就是倒序排列,

然後題目中要求的是:如果這個日曆的變化過程中,有乙個排列的逆序總數達到某個特定的值的話,就會世界末日,我們要求世界末日的日期,也就是求世界末日時這個日曆的排列。

那麼這個排列會滿足兩點:

1、這個排列應該是盡可能字典序小的乙個排列,因為這個日曆的變化規律是從字典序小到字典序大,中間有世界末日的話,就沒後邊字典序大的什麼事了,所以我們應該讓這個排序盡可能小。

2、這個排列的逆序總數是題目中要求m,這裡說下逆序總數的意思:就是這乙個排列裡,前邊的數比後邊的數大的話,就是乙個逆序,這兩個數就形成了乙個組合,我們叫逆序對。逆序總數就是在這乙個排列中,總共有多少逆序對。

比如說:

1  2  3   逆序總數為0     因為這是順序排列,每乙個數都小於它後邊的,所以沒有逆序對。

1  3  2   逆序總數為1     因為3大於2,只有這乙個逆序對,所以逆序總數為1

3  2  1   逆序總數為3     因為3大於2,3大於1,2大於1,有三個逆序對,所以逆序總數為3

那麼接下來我們就要找這個乙個排列,他要盡可能字典序小的同時,滿足逆序總數的要求

首先呢,暴力是肯定不行的,如果你遍歷每乙個排列,並且查詢每乙個排列的逆序數,這裡資料最多10的四次方,肯定會超時。

我們要知道:乙個長度為n的排列的逆序對的最大值為n*(n-1)/2,題目中給的m肯定不會大於這個值,

這道題的想法呢,就是一步一步的走,然後每一步都走最優的,等到最後就是最優解了。

一共有n個數的排列,我們就乙個乙個的排,每排乙個都讓它最優

我們從排列裡乙個乙個的拿,順序是從小到大的拿,拿完乙個拿下乙個,也就是說每次我拿的數,都是剩下沒有排列的數中最小的,現在假設我們拿的這個數是i(i從1開始),我們拿走它,然後這個排列的長度就變成n-i了,長度為n-i的排列的逆序對的最大值是(n-i)*(n-i-1)/2,這個時候我們拿它和m比,

如果m小於等於這個逆序對的最大值,說明什麼呢,說明我這個最小的數不用管逆序對的事,因為我這剩下的n-i個數都可以產生大於等於m的逆序對數,所以我就讓這n-i個數來管逆序對的事就行了,我這個最小的數不管那些,那最小的數管哪些呢,我們前邊提到我們要讓這個排列盡可能的字典序小,那什麼情況下字典序小呢,當然就是高位的數越小,字典序越小,所以我們就把這個最小的數放在排列第一位,這樣就能讓這個排列的字典序盡可能的小,是最優的!

如果m大於這個逆序對的最大值,那麼就說明,這個最小的數必須要管逆序對的事了,因為這剩下的n-i個數最多最對能產生的逆序對數也不夠m用,所以這個時候必須要加上這個最小的數的貢獻才行,那麼這個時候這個最小的數放在**是最優的呢,放在最後是最優的,因為這個時候,逆序對數不夠用了,所以我們應該盡可能的產生更多的逆序對才好,如果我們把這個最小的數放在排列的最後面的話,那麼剩下的所有未排列的數都會與這個最小的數產生乙個逆序對,因為我們是按照大小順序來拿的,先拿的都會小於沒有排列的數,剩下的所有未排列的數都大於這個最小的數。這時,逆序對數就增加了n-i,這時候m就應該減去增加的逆序對數,我們要讓m顯示的是目前為止還差多少逆序對數,這樣方便後面不停的迭代判斷。每一步就是判斷剩下的數最多能產生的逆序對數的值和目前為止還差多少逆序對數的m值相比。如果這個值足夠m用,我們就把當前拿的這個數盡量放在排列前,這樣能讓排列的字典序盡可能小,如果不夠m用,我們就把當前拿的這個數放盡量放在排列後,這樣就能讓排列產生更多的逆序對。

然後就這樣一直迴圈就行了,

最後上**,**很少,,,,,,,

1 #include2 #include3 using namespace std;

4 int a[50005];

5 int main()

14 else

18 }

19 for(int i=1;i<=n;i++)

22 return 0;

23 }

這個思路的作者是洛谷的 zqy1018,我是看了它的題解明白了之後,才寫的這篇部落格,感謝。

洛谷P1338(末日的傳說)

只要是參加jsoi活動的同學一定都聽說過hanoi塔的傳說 三根柱子上的金片每天被移動一次,當所有的金片都被移完之後,世界末日也就隨之降臨了。在古老東方的幻想鄉,人們都採用一種奇特的方式記錄日期 他們用一些特殊的符號來表示從1開始的連續整數,1表示最小而n表示最大。創世紀的第一天,日曆就被賦予了生命...

洛谷P1338 末日的傳說

qaq本來不是多難的題,然鵝我折騰了半天。看到乙個挺不錯的想法 我們知道,對於乙個長度為n的序列而言,其最大的逆序對的個數為n n 1 2,題目是要求乙個逆序數為m的字典序最小的序列。那我們不妨從1開始考慮每乙個數的排列,這樣每次考慮的都是當前最小的數 如果把這個數放在最前面,而剩下的數的排列的逆序...

P1338 末日的傳說 (逆序對)

題目鏈結 題面 題解 如何讓逆序對數為m的序列字典序最小呢?假設位置p是最後乙個原始序列的位置,那這個點應該盡量靠右,才能使得字典序最小。而為了保證有m個逆序對,要求p後面的逆序對數盡量大。需要降序排列。這樣問題就轉成找點p,同時在找到p時還需要知道 m 後面所有逆序對數剩餘的值,這個值要在點p身上...