洛谷 P1053 篝火晚會 解題報告

2022-04-30 06:48:08 字數 1717 閱讀 7178

佳佳剛進高中,在軍訓的時候,由於佳佳吃苦耐勞,很快得到了教官的賞識,成為了「小教官」。在軍訓結束的那天晚上,佳佳被命令組織同學們進行篝火晚會。一共有n個同學,編號從1到n。一開始,同學們按照1,2,……,n的順序坐成一圈,而實際上每個人都有兩個最希望相鄰的同學。如何下命令調整同學的次序,形成新的乙個圈,使之符合同學們的意願,成為擺在佳佳面前的一大難題。

佳佳可向同學們下達命令,每乙個命令的形式如下:

(b1, b2,... bm -1, bm)

這裡m的值是由佳佳決定的,每次命令m的值都可以不同。這個命令的作用是移動編號是b1,b2,…… bm的這m個同學的位置。要求b1換到b2的位置上,b2換到b3的位置上,……,要求bm換到b1的位置上。執行每個命令都需要一些代價。我們假定如果乙個命令要移動m個人的位置,那麼這個命令的代價就是m。我們需要佳佳用最少的總代價實現同學們的意願,你能幫助佳佳嗎?

輸入檔案的第一行是乙個整數n(3 <= n <= 50000),表示一共有n個同學。

其後n行每行包括兩個不同的正整數,以乙個空格隔開,分別表示編號是1的同學最希望相鄰的兩個同學的編號,編號是2的同學最希望相鄰的兩個同學的編號,……,編號是n的同學最希望相鄰的兩個同學的編號。

輸出檔案fire.out包括一行,這一行只包含乙個整數,為最小的總代價。如果無論怎麼調整都不能符合每個同學的願望,則輸出-1。

首先吐槽一下出題人的語文水平我自己的讀題水平吧

槽點1:我以為是改位置,而不是改號,想了無敵久

槽點2:我以為是只能從1號改到m號...

手動模擬一下,我們可以發現,更改每乙個人的位置到隨便每個位置其實只需要花費1的代價就行了

那麼,問題就轉化成了,求解不用動的人的人數的最大值。

再次模擬,目標環是唯一的

那麼\(o(n^2)\)的做法出來了,把目標環切成鏈,與原環的鏈匹配,找最大的。

如何優化?

我們在腦子裡畫兩個圈圈,我們通過轉動上面的圈圈讓兩個圈圈的匹配點盡可能的多。

現在圈還沒動,現在我們只看逆時針,上面的圈的每個點都會逆時針轉\(i\)個格仔與下面的對於點重合

那麼,如果很多人都轉動的是乙個定值\(k\),那不就拿到最優了!

當然,還要順時針做一遍。

code:

#include #include #include using namespace std;

const int n=50010;

int n;

int g[n][2];

int p[n],used[n],f[n];

void dfs(int now,int cnt)

if(!used[g[now][1]])

dfs(g[now][1],cnt+1);

}int main()

dfs(1,1);

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

f[(p[i]+n-i)%n]++;

int ans=0;

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

ans=max(ans,f[i]);

memset(f,0,sizeof(f));

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

f[(n*2-p[i]-i)%n]++;

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

ans=max(ans,f[i]);

cout<2018.4.29

洛谷P1053 篝火晚會

題目 模擬,構造出整個數列,要求的就是這個數列需要經過多少次操作得到 但是,這其實是乙個環,編號為1的可以放任意乙個位置,每一位都可以右移一位,最右邊的一位移到第一位 後文直接叫右移 而且,第乙個人可以選擇左邊a 1 右邊b 1 也可以左邊b 1 右邊a 1 所以環還可以倒過來。比如題中所給資料 4...

洛谷 P1053 篝火晚會

佳佳剛進高中,在軍訓的時候,由於佳佳吃苦耐勞,很快得到了教官的賞識,成為了 小教官 在軍訓結束的那天晚上,佳佳被命令組織同學們進行篝火晚會。一共有nn n個同學,編號從11 1到nn n。一開始,同學們按照1,2,n1,2,n1,2,n的順序坐成一圈,而實際上每個人都有兩個最希望相鄰的同學。如何下命...

P1053 篝火晚會

至於思路以及 解釋,個人覺得洛谷的題解已經很清楚了,故就不多解釋了 有一點不是很清楚,就是如果將c陣列的初始值定義為 正 c 0 1 c 1 l 1 反 c 0 1 c 1 r 1 時會wa乙個點,但在我看來好像並沒有什麼區別,如果有人知道,可以在下面告訴我,萬分感謝 include include...