P1338 末日的傳說 (逆序對)

2021-10-07 22:43:36 字數 1490 閱讀 8520

題目鏈結

題面:

題解:如何讓逆序對數為m的序列字典序最小呢? 假設位置p是最後乙個原始序列的位置,那這個點應該盡量靠右,才能使得字典序最小。而為了保證有m個逆序對,要求p後面的逆序對數盡量大。需要降序排列。

這樣問題就轉成找點p,同時在找到p時還需要知道 m-後面所有逆序對數剩餘的值,這個值要在點p身上修改。

則我們現在可以直接輸出序列。 1)p之前的部分按照順序輸出 2)輸出p,如果後面逆序對不夠,則需要修改p點再輸出。 3)逆序輸出p之後的部分,注意如果p之前改點了,需要多判斷一下。

**:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define llu unsigned ll

#define ld long double

#define iu unsigned int

using

namespace std;

const

int inf=

0x3f3f3f3f

;const ll lnf=

0x3f3f3f3f3f3f3f3f

;const

double dnf=

1e16

;const

double pi=

acos(-

1.0)

;const

int mod=

1e9+7;

const

int maxn=

10100

;int

main

(void

)//一共需要cnt+1位來形成這m個逆序對

cnt=n-cnt;

//令cnt=n-cnt

//那麼cnt-1位是不需要動的

for(

int i=

1;i)printf

("%d "

,i);

//轉折點為cnt+minn,那麼他後面有cnt,cnt+1,。。。,cnt+minn-1共minn個數比它小

//形成minn個逆序對

printf

("%d "

,cnt+minn)

;//剩下的都是降序排列,形成盡量多的逆序對

for(

int i=n;i>=cnt;i--)if

(i!=cnt+minn)

printf

("%d "

,i);

return0;

}

P1338 末日的傳說 逆序數對

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

P1338 末日的傳說

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

洛谷P1338(末日的傳說)

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