CF round#205 D

昨天做CF D題,是neko搞出來的,賽後看了一下standing上別人的代碼,記下對這道題的理解。

problem link: http://codeforces.com/contest/353/problem/D

首先來一個最短的代碼:


for(int i = 0; i < n; i++) {
    if(str[i] == 'M') x++;
    else if(x) y = max(y+1, x);
}
printf("%d\n". y);



x是前面boys的累加,a表前面最近一個girl,b表當前girl,y0是a所需要的時間,y1是b所需要的時間。

<1>首先,y0+1和x是y1的兩個下界。

     證明:不論a、b相對位置如何,x是y1的一個下界都沒有爭議吧,因爲b至少要跟x個人交換嘛; 若a、b是相鄰的,則顯而易見y1 = y0 + 1;若a、b不相鄰,當然,下界還是(y0+1, x)~~對了,我這裏說的“下界”只是爲了說明y1肯定比x和y0+1大

<2>兩個下界的最大值就是當前girl b所需要的時間

    證明:如果b能暢通無阻地走到其目的地,則所需時間爲x;

              如若不能,說明在某個時刻a會擋住b,即a、b貼在一起。OK,既然知道她們倆在某個時刻會貼在一起,而移動又都是同步的,那y1 = y0 +1

  這種思路的巧妙性在於,它不去討論兩個girls中間有多少個boys,而是直接就分成上述兩種情況,掩蓋了各種討論的種種細節。


       這種做法給我的啓發,遇到這種需要分很多種情況的題,不妨換種思路,換種分情況的法子。像這道題,因爲交換是同步的,然後每一次交換都把序列變得亂七八糟的沒有規律。如果找到“不論怎樣,每個girl的相對順序不變”,“當前girl所需的時間只跟前面那個girl移動的時間和前面總boys數有關”這兩個性質,大概就能分析出來了。


ps : if(x) .... 這是爲了判斷前導‘F’的情況。






再來一發:

for(int i = 0; i < n; i++) {
    if(str[i] == 'F') {
        time = i - female++;
        if(time) time += continousFemale++;
    } else {
        continousFemale = max(0, continousFemale-1);
    }
    ans = max(ans, time);
}

這份代碼我並沒理解到它的精髓。

continousFemale其實就是當前女孩所需要等待的時間(所需時間 = 移動到目的地的步數 + 等待時間),有種同性相加,異性相消的感覺...

隨便記點小理解吧~    str[i] == 'M',說明後面的女生又可以少一個空閒時間了(假設continousFemale > 0),因爲多了一個str[i]要交換呀...

我根據這份代碼猜測出一個結論:把girl看成1,boy看成-1,得到一個1/-1序列。若有0~i-1的前綴和sum都大於等於0,則對於當前位置i上的女生,她的等待時間爲sum。

如果遇到前綴和小於0的時候,我們把前面砍掉,sum清空爲0,重新從下一個位置開始計算一個新的前綴和sum。

只是猜測,不知對錯,不知怎麼證明,但我覺得要是搞懂這個點應該是很有價值的。有想出證明的大神路過求告知~~



第3分比較常規,跟第2分類似:

for(int i = 0; i < n; i++) {
    if(str[i] == 'F') to[i] = dst++;
    else to[i] = -1;
}
delay[0] = 0;
for(int i = 1; i < n; i++) {
    if(to[i] == i) delay[i] = 0;
    else if(str[i] == str[i-1] && str[i] == 'F') delay[i] = delay[i-1] + 1;
    else if(str[i] == str[i-1] && s[i] == 'M') delay[i] = max(0, delay[i-1] - 1);
    else delay[i] = delay[i-1];
}
for(int i = 0; i < n; i++) 
    if(str[i] == 'F' && to[i] != i) 
        ans = max(ans, i - to[i] + delay[i]);

發佈了52 篇原創文章 · 獲贊 0 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章