題目鏈結
題面:
題解:如何讓逆序對數為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表示最大。創世紀的第一天,日曆就被賦予了生命...