1. 程式人生 > 其它 >[Codeforces Round #794 (Div. 2) E](https://codeforces.com/contest/1686)

[Codeforces Round #794 (Div. 2) E](https://codeforces.com/contest/1686)

Codeforces Round #794 (Div. 2) E

題意:給你一個括號序列,請輸出最少翻轉次數以及方案,使得該括號序列成為一個合法序列。

題解:個人感覺是相當不錯的一道思維題。

首先,我們不難想到要讓括號序列做一個轉換,'(' 變為1,')'變為-1,最後成為一個整數陣列,如果這個陣列的全部字首和都是非負數,則證明這個序列一定是合法括號序列。

接下來的這個性質就非常有意思。

性質1:任何題意中的括號序列,最多隻需要兩次就可以變換為一個合法序列。

這個性質好像神來之筆,其實也有跡可循,我們希望所有的字首和都是一個非負數,結合翻轉,我們發現一個所有字首和之中,字首和最大的位置或許很有用。

不妨假設字首和最大的位置為\(i\)(如果有多個位置最大,任取其中一個),順便定義原數列的字首和陣列\(pre\).

我們可以發現,如果我們把\([1,i]\)做個翻轉,不難看出翻轉後的字首和為\(pre_i - pre_j (j<=i)\),這個一定滿足非負 .那麼如果\(j>i\)呢,也非常簡單,我們只需要把\([i+1,2*n]\)再做個翻轉就好,簡單證明如下,首先數列無論如何翻轉,最後所有數的和一定是0,我們可以得到,翻轉後的字尾和其實等於\(pre_j - pre_i\),由於\(pre_i\)一定最大,所以\(pre_j - pre_i <= 0\),則字首和為\(0-(pre_j - pre_i)>=0\)

,得證。

那麼既然最多為2次,我們就只需要考慮,0次和1次翻轉就合法的情況了,首先0次的,就是在一開始判斷一下,很好處理,我們仔細思考一下關於一次翻轉就合法的情況。

首先我們找到所有\(pre_i\)為負數的情況,定義其中最小的為\(l\),最大的為\(r\),我們首先可以發現如果最後翻轉的區間為\([L,R]\),則一定要滿足\(L<=l,R>r\),簡單證明如下,如果不滿足的話,那麼一定有字首為負值,那麼一定不合法。但是得到這個結論之後,發現情況還是太多,我們需要更進一步的性質。

那麼,新性質來了。

性質2:如果存在\([L,R]\)翻轉使得原序列合法,那麼\([L_1+1,R_1]\)

翻轉也一定合法。我們定義\(L_1\)為所有滿足\(L<=l\)之中字首最大的位置,\(R_1\)也同理,為滿足\(R>r\)之中字首最大的位置.

接下來為簡單證明: 首先\([L,R]\)之外的字首一定滿足合法條件,除此之外,如果全部滿足\(pre_{R_1} - pre_i + pre_{L_1} >= 0\),則證明合法,對於\(L_1 <= i <= R_1\),如果存在\(pre_{R_1} + pre_{L_1} < pre_i\),則有\(pre_i > pre_{L_1}\)與條件矛盾,由此,可反證性質成立。