佳佳剛進高中,在軍訓的時候,由於佳佳吃苦耐勞,很快得到了教官的賞識,成為了「小教官」。在軍訓結束的那天晚上,佳佳被命令組織同學們進行篝火晚會。一共有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...