$NOIp$提高組歷年題目復習


寫在前面

一個簡略的\(NOIp\)題高組歷年題目復習記錄.大部分都有單獨寫題解,但懶得放\(link\)\(QwQ\).對於想的時候兜了圈子的題打上\(*\).

\(NOIp2018\ [4/6]\)


### 鋪設道路 模擬/結論

從左往右掃一遍,掃到高度比前一個大的就累加上兩者的高度差.

貨幣系統 \(dp\)/背包

考慮從貨幣系統中去掉不必要的貨幣,不必要的貨幣其實就是能被其他貨幣表示出的貨幣.貨幣無限多,可以看成完全背包問題,設\(f_i\)為數值\(i\)能否被小於它的數表出.

\(*\)賽道修建 二分/貪心/樹形

最小的最大,容易想到二分,變成判定性問題.再貪心+樹形\(dp\)即可.

發現我已經不會寫這個貪心了,於是又回去看了看原來的題解.\(copy\)一下關鍵句子:"對於每個結點,把子結點上傳的鏈長加上父與子之間的邊權加入\(multiset\).首先找到值已經大於等於\(mid\)的,直接累計答案.然后考慮內部匹配,從小到大掃,找到另一個最小的使得兩者相加大於等於的值,\(mid\)刪去這倆結點並且累計答案.最后向父結點上傳剩余的鏈里面最長的就行."

旅行 圖論/貪心/搜索

首先樹的情況做法非常顯然,直接從\(1\)開始,每次貪心地選擇能走的結點里字典序最小的走就行,不能走就退回上一城市.

\(m=n\)的情況,也就是樹上有個環,顯然這個環上一定有一條邊不會被走過,枚舉這條邊是啥,然后按照樹的做就行.

然而發現忘記怎么找環以及刪邊了\(QwQ\),又回去看了下以前的\(code\)然后\(get\)了,其實是一個比較暴力的方法.環就直接\(dfs\)找,刪邊的話就記個全局變量記邊的兩個端點,按樹的情況做的時候強制不走這條邊就行.

填數游戲


### 保衛王國

\(44pts\)的暴力樹形\(dp\)還是很好寫的叭.


## $NOIp2017\ [5/6]$
### 小凱的疑惑 打表/數學

這題表好打規律也好找\(QwQ\).證明並不想寫了,可以看\(gql's\ blog\).

時間復雜度 模擬

模擬題.之前一直覺得自己寫不出來這種超級大模擬,也不想寫.之前考托腮的考試有一個大模擬,考試嘛當然不得不寫了.發現其實慢一點,細心一點也是可以寫好的.打算再寫一次\(QwQ\),但不是現在\(QwQ\).

逛公園 圖論/記搜/\(dp\)

前不久才寫的,這題\(dp\)有點難寫,記憶化搜索好寫多了.我永遠喜歡記搜.

奶酪 並查集

簡單題\(QwQ\),去年就會了.不過我會的應該是個比較暴力的做法:就先\(n^2\)枚舉算\(dis\),如果相連就加入一個並查集,最后再枚舉上表面的洞和下表面的洞,看有沒有聯通的.

寶藏 狀壓\(dp\)

也是前幾天才寫的\(QwQ\).由於代價和層數有關,所以直接枚舉層和已選集合,再枚舉一些點加入,強制它們是下一層的,至於連哪條邊,直接暴力枚舉取\(min\)就行.(其實感覺這題做法挺暴力的,但覺得巧妙的一點是,不一定要每一步都算出精確答案,只要最終答案正確就可以了.

列隊

好難不會.


## $NOIp2016\ [5/6]$
### 玩具謎題 模擬

簡單模擬.

天天愛跑步


### 換教室 期望/$dp$

期望\(dp\).轉移有點復雜要細心一點.

組合數問題 前綴和/組合數

觀察\(k\)的取值可以知道這里的組合數\(C\)不能直接通過公式\(C_n^m=\frac{n!}{m!(n-m)!}\).又因為這里的\(n,m\)都挺小,所以可以直接遞推\(C_n^m=C_{n-1}^m+C_{n-1}^{m-1}\)算.記一個前綴和就行了.

\(*\)蚯蚓 模擬/單調性

\(80pts\)的做法是很容易想到的,復雜度是\(mlog(n+m)\).優化是去掉這個\(log\),發現題目中隱藏的單調關系就可以不用\(priority\_queue\)了.注意到先切的蚯蚓的較長部分比后切的長,較短部分也是這樣.直接開三個數組,一個存被切過的切是較長的一個,一個存較短的,一個存還每被切過的.每次取三個數組最大的最大就行.

憤怒的小鳥 搜索/狀壓

兩種解法:搜索/狀壓\(dp\),都挺好寫的.就講下狀壓的小優化叭,就是最終要算的是\(f_S\),對於當前狀態\(f_i\),枚舉一個拋物線\(j\)來轉移,當且僅當\(j\)經過\(lowbit(i)\).這樣優化之后復雜度是\(O(Tn2^n)\).

對了,還有精度問題要注意,開個\(1e-8\)的亞子就行.


## $NOIp2015\ [6/6]$
### 神奇的幻方 模擬

簡單模擬.

\(*\)信息傳遞 並查集/搜索

居然不怎么會做這題了\(QwQ\).

這題其實就是求一個有向圖的最小環,最小環算法的復雜度顯然是不行的.考慮這題有一個非常特殊的性質就是每個點的出度都為\(1\).這題主要有倆算法:

​ 1.並查集做法.就每次連一條邊就把它們加入一個並查集,再記一個\(d_i\)表示從\(i\)開始走到不能走,所走過的點數.對於當前加入的邊\((u,v)\),如果它們同屬於一個並查集,也就是說\(v\)已經有一條路徑到\(u\)了,現在又有一條路徑從\(u\)\(v\),這就形成了一個環,環大小為\(d_v+1\) ;否則就合並\(u,v\),且維護\(d_u=d_v+1\).注意到這里的\(d\)不是這么簡單就可以維護得了的,還要改造一下\(find\)函數來維護.

​ 2.搜索做法.直接搜所有的環.從每個點出發找環,記錄走到每個點的時間,如果當前點再走一步就會走到一個標記過的點,那就出現了一個環,環的大小就是現在的時間減去下一個走到的點的時間再\(+1\).由於每個點至多在一個環里,所以搜過的點沒必要再搜,剪枝即可.

    $upd\ on\ 11.6:$在做一個與這題挺類似的一題的時候,想到了另外一個方法. ( 發現題解里有這個方法只是之前沒看$QwQ$,反正講下.就直接拓撲排序確定哪些點在環上,再遍歷每一個環確定它的大小,最后在所有環里取$min$就可以了,復雜度$O(n)$.超級好寫$5\ min$就過了.

### 斗地主 搜索

我還不會斗地主呢.暴搜+最優性剪枝就可以過.

跳石頭 二分

二分板子題.

子串 \(dp\)

剛做的,不難.唯一要\(D\)自己的是居然不記得滾動數組了!!

運輸計划 二分/樹上差分

題意是求將哪條樹邊變成\(0\)可以使得給定的路徑中,最長的最短.顯然考慮二分,對於一個二分值\(mid\),將長度大於\(mid\)的路徑拎出來,計算每條邊被這些路徑經過多少次,去掉經過次數最多的邊,再看去掉該邊后能否滿足題意即可\(check\),計算路徑被經過多少次就樹上差分下就好.


\(NOIp2014\ [6/6]\)


### 生活大爆炸版石頭剪刀布 模擬

入門模擬題.

聯合權值 樹形/貪心/前綴和

以任意結點為根,與一個點距離為\(2\)的點有它的祖父,孫子,兄弟.前面兩個都好算,唯一有點技巧的是兄弟.兄弟這里顯然不可以直接枚舉着算,考慮用前綴和優化.假設一些兄弟的權值是\(x,y,z\),那么貢獻是\(x\cdot y +x\cdot z+y\cdot z\),不就是\(x\cdot y+(x+y)\cdot z\)嘛.求和就是這樣,再看兄弟結點間的聯合權值怎么更新最大值,這里貪心一下,直接選兩個權值最大的兄弟結點就行.

飛揚的小鳥 \(dp\)

上周復習背包的時候還復習了這題.考慮\(dp\),\(f_{i,j}\)表示到位置\((i,j)\)所需的最小點擊屏幕數.可以點擊屏幕多次上升,說明上升是完全背包.每秒只能下降一定高度,說明下降是\(01\)背包.

無線網絡發射器選址

暴力即正解.

尋找道路

先把所有不滿足條件\(1\)的點去掉,然后直接\(dijkstra\)即可.怎么判斷滿不滿族條件呢?建反圖,從終點\(dfs\)一遍,記錄每個點的入度,再從起點\(dfs\),記錄每個點的出度,如果入度\(=\)出度,那么就是滿足條件\(1\)的點.

解方程

枚舉解,代入方程中檢驗即可,用秦九韶算法計算.有一個細節是\(a_i\)太大了,沒有辦法直接讀入,直接再快讀里邊讀邊\(\%\)就行.


## $NOIp2013\ [5/6]$
### 轉圈游戲 找規律

答案是\((x+m\cdot 10^k)\ mod\ n\).

火柴排隊 貪心/離散化/逆序對

要得到最小距離顯然是第一列中最小的配第二列中最小的,次小配次小..這樣推下去.所以可以把序列離散化一下,把第一個序列對應成\(1,2,3,..,n\),第二個序列依照相對位置得到一個序列,我們的目標就變成了交換第二個序列,使得它變成單調遞增的序列.每交換一次,一定是一個大數交換到了后面,也就是逆序對減小了\(1\),那么答案顯然就是逆序對的個數.歸並排序或者樹狀數組都可以求.

積木大賽 模擬/結論

鋪設道路.

\(*\)花匠 \(dp\)

\(f_{i,0/1}\)表示考慮到第\(i\)盆花,這盆花相對上一盆是上升/下降的,保留的最多數目.一個顯然的轉移是枚舉上一盆是什么,取\(max\)即可.這樣可以獲得\(80pts\).

其實總感覺這題和求\(LIS\)挺像的.所以來想想\(LIS\)是怎么求的,有一種方法是直接記錄當前最長的上升序列,對於掃到的下一個元素\(x\),若\(x\)大於當前序列的尾值,就直接將它加入,否則就用\(x\)來替換選出序列中比它大的第一個元素.這樣貪心地替換一定是最優的,因為給后面的選擇留出了更多的空間.

再來看這題,先類似地改變下\(dp\)數組的意義,先只考慮條件\(1\),\(f_{i}\)表示的是一個合法序列的第\(i\)個元素是啥.\(len\)表示當前合法序列的長度.假設\(i\)元素是波谷,若\(h_{i+1}>h_i\),那么直接將序列長度\(+1\)就行,否則,將\(i+1\)代替\(i\)成為新的波谷顯然是不劣的.由於我們只需要知道當前序列的最后一個元素,所以\(f\)數組也是不需要的,直接開一個變量存一下就行.然后再來考慮條件\(2\),和上面類似地做一遍就行.

華容道

還沒做呢.


## $NOIp2012\ [4/6]$
### Vigenère 密碼 模擬

沒啥好說.

國王游戲 貪心

發現兩個人的位置關系只能影響他們兩者的貢獻,不會影響到其他人的貢獻.所以先只考慮兩個人\(i,j\),設\(\prod_{k=1}^{i-1}=t\).

\(i\)在前,則貢獻是\(max(\frac{t}{b_i},\frac{t\cdot a_i}{b_j})\);若\(i\)在后,則貢獻是\(max(\frac{t}{b_j},\frac{t\cdot a_j}{b_i})\).

考慮\(i\)在前更優需要滿足什么條件.注意到我們現在關心的是這兩個\(max\)再取\(max\)的數屬於前面還是后面.換言之,我們現在關心的是四個元素中最大的元素是誰.

顯然\(\frac{t}{b_i}<\frac{t\cdot a_j}{b_i},\frac{t}{b_j}<\frac{t\cdot a_i}{b_j}\).所以只要知道\(\frac{t\cdot a_j}{b_i}\)\(\frac{t\cdot a_i}{b_j}\)的大小關系就行.現在要\(i\)在前面更優的條件是\(\frac{t\cdot a_i}{b_j}<\frac{t\cdot a_j}{b_i}\).轉化下:\(a_i\cdot b_i<a_j\cdot b_j\).所以,只要以之為關鍵字排個序就行.

開車旅行 倍增

暑假有天寫了好久都沒寫出來然后就棄了\(QwQ\).我這兩天會寫的!

同余方程 數學

光考試就考了兩遍了我當然會了辣\(QwQ\).(其實我還背不下來每次都要現推

借教室 線段樹/二分

首先顯然要離散化天數,這樣就變成\(10^6\)級別的了.具體來說有兩種方法.

\(1.\)簡單粗暴線段樹.直接區間加,維護區間\(min\)需要的教室數減去有的教室數,若\(min<0\),就不合法了.

\(2.\)二分.如果第\(x\)個人借完教室之后,存在某一天教室數\(<0\),那么第\(x+1,x+2,..\)個人借完教室之后,一定存在某天教室數\(<0\),所以答案具有單調性,可二分.\(check\)就記一個差分數組,然后直接讓前\(mid\)個人借完教室,再求前綴和看有沒有不合法的即可.

疫情控制

還沒做\(QwQ\).


## $NOIp2011\ [6/6]$
### 鋪地毯 模擬

簽到題.

選擇客棧 計數

要求一對客棧滿足顏色相同且中間有權值不大於\(p\)的客棧,求這樣的客棧對數.

掃描一遍所有的數組,記錄一個\(sum1_i\)表示當前掃到的客棧中色調為\(i\)的有多少個,\(sum2_i\)表示色調為\(i\)且與當前客棧間隔有權值不大於\(p\)的客棧的數目.掃到一個權值不大於\(p\)的客棧時就更新所有的\(sum2_i\).

\(Mayan\)游戲 搜索/模擬

大模擬,但感覺這題比時間復雜度呆一點,簡單一點.

計算系數

首先把\(a,b\)去掉,顯然最后的系數包含一個\(a^nb^m\).眾所周知,\((x+y)^k\)展開之后的系數是楊輝三角的第\(k\)行的某個數.所以,求個楊輝三角就行.

然而這題有更優秀的做法,我們只需要楊輝三角上的一個數值就好,沒必要推出整個三角.思考楊輝三角還有什么意義?組合數!所以最后答案就是\(C_{k}^n\cdot a^n\cdot b^m\).

聰明的質監員

\(S-Y\)的絕對值去掉,將問題分為兩個部分,一個是\(S>Y\)時要求\(S\)越小越好,一個是\(S<Y\)時要求\(S\)越大越好.現在我們只考慮第一個問題.顯然答案具有單調性,可二分.怎么\(check\)呢?記錄兩個前綴數組:\(a_i=\sum _{w_j\geq W}1\),\(b_i=\sum _{w_j\geq W}w_j\).

觀光公交 貪心

考慮對一個\(D_i\)使用加速器給答案的貢獻是多少.

具體來說是這樣的:首先要坐車到達\(D_i\)的這些乘客時間肯定會減少,在\(D_i\)等車的乘客的時間肯定會減少,這取決於車到達的時間是否不早於最后一個乘客到達的時間,假若會使得在\(D_i\)等車的乘客時間減少,那么又可能會使得\(D_{i+1}\)等車的乘客時間減少,類似的情況.

所以,維護兩個數組\(arr1_i\)\(arr2_i\)表示汽車到達\(i\)的時刻和最后一個乘客到達\(i\)的時刻.對\(D_i\)使用一個加速器的貢獻就是在\([i,j],arr1_j-1>arr2_j-1且arr1_j\leq arr2_j\).這段區間下車的乘客數目.貪心地選擇這樣數目最多的\(D_i\)使用加速器即可.

覺得原來寫的\(blog\)寫得挺清楚的.


## $NOIp2010\ [4/4]$
### $*$引水入城 記搜

如果能滿足要求,那么一個蓄水廠所輸送水到的沙漠城市一定是連續的一段.假若只能輸送到\([l_1,r_1]\)\([l_2,r_2]\),那么顯然\([r_1+1,l_2-1]\)這段區間不能有水利設施(因為這個聯通塊整個高於周圍的聯通塊),與"能滿足要求"矛盾,故假設不成立.

\([l_i,r_i]\)表示能蓄水廠\(i\)能輸水到的沙漠城市區間,用記憶化搜索求出所有的\([l_i,r_i]\),順便記錄每個沙漠城市是否被覆蓋到用來判定有無解.最后就轉化成了一個最小線段覆蓋問題,貪心做就行.

關押罪犯 二分/二分圖/貪心/並查集

顯然答案具有可二分性.於是二分這個答案,則怨氣值大於\(mid\)的不能放在同一監獄,二分圖染色\(check\)就好.

還有並查集做法,先按照怨氣值從大到小排序.記錄每一個罪犯的第一個掃到的發生沖突的罪犯,如果掃到兩個罪犯其中一個罪犯的對手有記錄的對手,那么就把他們兩個分到一個監獄.

機器翻譯 模擬

簡單模擬.

烏龜棋 \(dp\)

發現\(b\)值很小,於是把它記入狀態.\(f_{i,a,b,c,d}\)表示走到第\(i\)個位置,還有卡片\(1\ a\)張,\(2\ b\)張,\(3\ c\)張,\(4\ d\)張最多得到的分數.發現數組開不下,直接將第一位省略掉就好了.


## $NOIp2009\ [4/4]$
### 潛伏者 模擬/字符串

簡單題,但要認真讀題.

\(Hankson\)的趣味題 數學

\(gcd(x,a_0)=a_1\rightarrow\ gcd(\frac{x}{a_1},\frac{a_0}{a_1})=1\)

\(lcm(x,b_0)=b_1\rightarrow gcd(\frac{b_1}{x},\frac{b_1}{b_0})=1\)

直接\(O(\sqrt b_1)\)枚舉\(x\),\(check\ x\)是否滿足\(a_1|x,x|b_1\)和上面的兩個等式,貢獻答案,還要算\(\frac{b_1}{x}\)的答案.以為自己寫了個暴力,結果\(AC\)\(QwQ\).

再講一個更加優秀的方法.先篩出\(\sqrt{2\cdot 10^9}\)內的質數然后將\(a_0,a_1,b_0,b_1\)暴力分解質因數.因為\(gcd\)是取指數的最小值,\(lcm\)是取指數的最大值,所以可以對每個質數得出一個可取數量的區間,乘起來就是答案了.

\(*\)最優貿易 圖論/\(dfs\)/縮點

先縮點把圖上的環去掉,然后直接一遍\(dfs\)更新答案即可.這是一種比較容易想到的方法.下面講一種更加巧妙且實現更為簡單的方法:

設價格為\(w_i\),記\(mi_i\)為從\(1\)\(u\)路徑上經過的最小的\(w\),\(mx_i\)為從\(u\)\(n\)路徑上經過的最大的\(w\),那么若\(1\)可達\(i\)\(i\)可達\(n\),就可以用\(mx_i-mi_i\)更新答案.

維護一個點\(i\)能不能被\(1\)到達和能不能到達\(n\)是可以簡單維護的.現在的問題是如何維護\(mi_i,mx_i\).考慮按\(w\)從小到大排序的順序去更新其他點,這樣每個點的\(mi\)最多只被更新一次,\(mx_i\)也是類似地做. (像這樣用一個元素的值去更新其他元素的最小/最大值,都可以考慮排個序變成賦值操作.

靶形數獨 搜索

搜索+剪枝.

在此復習下剪枝的幾個方法 (算法競賽上蒯的:

比較常用的:可行性剪枝/最優性剪枝

容易忽略的:優化搜索順序/記憶化

還有一個沒\(get\)的:排除等效冗余.在搜索樹上如果能夠判定從當前結點沿着某幾條不同的分支到達的子樹是等效的,那么只需要對其中的一條執行搜索. (這個我還沒太\(get\).

\(NOIp2008\ [4/4]\)


### 苯小猴 模擬

入門題,送分送到位了\(QwQ\).

傳紙條 \(dp\)

經典\(dp\)題.兩條路徑一起走,設\(f_{x_1,y_1,x_2,y_2}\)表示第一條路徑走到\((x_1,y_1)\),第二條路徑走到\((x_2,y_2)\)時,兩條路徑的好心程度之和最大是多少.直接枚舉下一步往哪走轉移,注意不能走至同一個格子.

為啥這樣做可以保證\((x_2,y_2)\)一定不會再走到\((x_1,y_1)\)走過的位置呢?因為每次只能向下或向右走,所以\(x_1+y_1=x_2+y_2\),\((x_2,y_2)\)再走一步到達的格子的橫縱坐標之和一定是\(x_1+y_1+1\),而\((x_1,y_1)\)走過的地方的橫縱坐標之和小於該值,所以可以保證.有個更簡單的解釋就是,每個時刻可能在的地方都是一條與橫坐標成\(45\)度角的一條直線上,這些直線互相不重合.

顯然\(dp\)中有一維可以由別的維度推出,可以省略.

火柴棒等式 搜索/枚舉

開始感覺這題直接搜不一定能過,因為理論上\(n=24\)時,可以組成\(11111\),枚舉下就\(1e10\)了.於是寫了個搜發現\(n=24\)時只能組成\(30261\)個數,把這些數按照用的火柴棒數拍個序,枚舉兩個加數,及時\(break\)循環是可以過的.

雙棧排序 棧/二分圖

先觀察可以單棧排序的條件是啥,具體來說:\(\forall i<j<k\),都沒有\(p_k<p_i<p_j\).簡單整理一下,就是不存在二元組\((i,j)\)滿足上述條件.

再來看雙棧排序.如果將序列分成兩個子序列使得它們分別可以單棧排序,那么這個序列就可以雙棧排序.將所有的二元組\((i,j)\)建出來,二分圖染色即可.最后要注意對操作的順序貪心,注意細節.

\(NOIp2007\ [4/4]\)


### 統計數字 $set/$排序

用個\(set\ or\ map\)維護一下不就好了.看了下標簽,其實可以直接排序算就行.

字符串的展開 模擬

去年暑假考過這題.看懂題模擬就成.

矩陣取數游戲 \(dp\)

注意到行與行之間是互相獨立的,可以分別計算每一行的最大貢獻,加起來就是答案了.

對於單獨的一行,是個典型的區間\(dp\).設\(f_{i,j}\)表示一行只剩下\([i,j]\)這個區間還沒有取的最大貢獻,轉移就枚舉這次取數是取\(i\)還是\(j\)去更新\(f_{i-1,j}\)或者\(f_{i,j-1}\).最后答案是\(max\{f_{i,i}+2^n\cdot a_i\}\).

樹網的核 樹形/枚舉

先考慮暴力做法叭.

首先可以對每個結點都\(dfs\)一遍求出所有的\(d_{i,j}\),這里取個\(max\)就知道了樹的直徑.把\(d_{u,v}=\)直徑的\(u\)記錄一下,預處理完了之后對每個這樣的\(u\ dfs\)一遍,維護一個棧,里面存當前路徑經過的點,找到一個點\(v\)使得\(d_{u,v}=\)直徑時,枚舉棧中的元素組成的路徑,用這個路徑去更新答案.這里有一個貪心的地方,就是假設\((u,v)\)是一條合法路徑,\((u,x)\)也是一條合法路徑,且\((u,v)\in(u,x)\),那么\((u,x)\)一定不會比\((u,v)\)劣.

結果就\(AC\)辣?感覺是\(n^4\)的復雜度\(QwQ\).加強版的這題在這里,我的代碼可以過\(n\leq 3000\).

對了,還有就是感覺這里超多\(min\)\(max\),一定要仔細搞清楚再寫.

\(NOIp2006\ [4/4]\)


### 能量項鏈 $dp$

典型的區間\(dp\),與合並石子大同小異.

金明的預算方案 \(dp\)/背包

簡單的有依賴的背包問題,由於最多只有兩個附件且附件不再有附件,所以不需要樹形背包就可做.典型的樹形背包題應該是[洛谷\(2014\)選課].不過這題還是要注意循環的順序,應該要把枚舉附件的循環放在最里面.

作業調度方案 模擬

直接模擬.

\(*2\)^\(k\)進制數 \(dp\)

\(f_{i,j}\)表示\(2^k\)進制數的第\(i\)位選了\(j\)的方案數.

\(f_{i,j}=\sum_{x=j+1}^{2^k-1}f_{i-1,x}\)

第一維可以滾掉,轉移可以前綴和優化,記一個\(s_{i,j}\)表示第\(i\)位選了不小於\(j\)的數的方案數.

\(WA\)了好久\(QwQ\),為啥函數里傳遞的數組不能用\(memset\ qaq\).


## $NOIp2005\ [4/4]$
### 誰拿了最多獎學金 模擬

入門模擬題,去年學結構體的例題.

過河

又沒懂題\(kk\).原來跳躍過河不一定要跳在石頭上面.

簡單\(dp\): \(f_i\)表示跳到位置\(i\)所經過的最少石頭數,可以獲得\(30pts\).

路徑壓縮( 好神仙吖\(QwQ\) :

假設現在可以走的步數是\(p\)\(p+1\),那么\(gcd(p,p+1)=1\),套上小凱的疑惑的結論可以知道\(p\cdot (p+1)-(p+p+1)\)之后的點都是可以用\(p\)\(p+1\)表示出來的.

所以直接把兩個石頭之間間距超過\(t\cdot (t-1)\)的變成這么多就行.


### $*$篝火晚會 結論/思維

題面也太鍋的了叭,其實這\(b\)個位置可以不連續\(QwQ\).

首先判斷一下有沒有解.我最開始想的是如果有兩個以上的人想和同一個人相鄰,那么無解.事實上,這並不能涵蓋所有的情況,應該是如果\(a\)想和\(b\)相鄰,而\(b\)不想和\(a\)相鄰,這種一廂情願的情況是不合法的,而且它涵蓋了我上面說的情況.

考慮最優策略.假設現在的序列和目標序列有\(k\)的元素不相同,我們可以通過若干次命令,這些命令的總代價為\(k\)來達到目的.具體來說,將每個不同位置上的數向它的目標位置連邊,一定為形成若干個環,每次對一個環操作就是最優策略.

最后狀態的環顯然是已知的,但是我們不知道\(1\)\(2\)位置上是啥,如果知道了這兩個位置上的數,那么所有位置上的數就都確定下來了.枚舉這倆位置上的數是啥,一共有\(2n\)種可能,再按照上面的結論計算不同位置的個數就行.然而這樣復雜度是\(O(n^2)\)的.

把枚舉\(1,2\)的位置抽象成這樣一個問題:有兩個嵌套的環,里面的環是\(1,2,3,...,n\),外面的環是\(p_1,p_2,p_3,..,p_n\),現在要旋轉外面的環使得兩個環對應位置上不同的數盡量的少. (注意,因為方向的問題,外面的環實質上是有兩種的,但這里只討論一種,另外同理).先隨便排一個外環,對每個位置求出要到達它的目標位置,需要外環順時針(逆也行,反正欽定一個)旋轉多少個位置,開個桶存旋轉\(x\)個位置有多少個位置會對齊.取桶里的最大值就行.


### 等價表達式 模擬

感覺是一個和時間復雜度差不多難度的模擬題.

注意這題有一個坑點是可能輸入里括號是不匹配的,這時就直接\(GG\)了.另外一個我覺得有點奇怪的地方就是我感覺我每行都讀了換行,但是仍然要在讀入字符串的時候加\(if(c=='r')c=getchar()\).

這題我寫的比較呆.首先一個大家都能想到的地方就是給\(a\)賦值,計算值比較.我是開了一個棧,每掃到一個做括號就加入棧,有括號就計算棧頂元素到該右括號之間的值.這樣就去掉了括號的限制,然后對序列掃三遍,分別計算乘方,乘法,和加減.

其實可以考慮這樣做:遞歸計算優先級最低的符號左右兩邊的算式,最后合並.還要考慮括號的情況,具體來說記一個\(p_i\)表示\(i\)位置上符號的優先級,在括號里的優先級要高於括號外的.放下\(gql\)小朋友的代碼.


## $NOIp2004\ [4/4]$

津津的儲蓄計划 模擬

它真的是道入門題,成為了我在洛谷做的第\(5\)道紅題.

合並果子 \(dp\)

區間\(dp\)入門題.

合唱隊形 \(dp\)

\(f_i\)\(1\)\(i\)的最長上升子序列的長度,\(g_i\)\(i\)\(n\)的最長下降子序列的長度.分別求出,答案就是\(max\{f_i+g_i\}\).

蟲食算 搜索

直接搜每個字母代表了了什么數字再\(check\).

優化下搜索順序,使得可行性剪枝發揮最大的作用.按照令\(p_s\)表示字母\(s\)在三個字符串中出現的最末的位置,按照\(p\)降序排的順序搜.

這題正解竟然是高斯消元\(QwQ\).然而並不想看了.

\(NOIp2003\ [3/4]\)


### 神經網絡 拓撲排序/模擬

拓撲排序模擬下就行.

偵探推理 模擬/字符串

暑假有天剛了好久這題.最后還是\(T\)成了\(80pts\).我會寫這題的!

加分二叉樹 \(dp\)

注意到一個子樹在中序遍歷的序列里是連續的一段區間(這句話很重要吖不要忘了\(QwQ\)).所以這題其實是個區間\(dp\).

\(f_{i,j}\)為區間\([i,j]\)組成一棵樹的最大加分,由於要輸出前序遍歷,所以還要記一個\(p_{i,j}\)表示\([i,j]\)樹以\(p_{i,j}\)為根時加分最大.按照區間\(dp\)套路轉移就行,枚舉根是哪個,從小區間轉移到大區間.

傳染病控制

其實看起來很貪心的亞子,但是又想不出貪心策略.那就搜索叭\(QwQ\),簡單搜索就能過.


## $NOIp2002\ [4/4]$
### 均分紙牌 模擬/貪心

將所有的\(A_i\)減掉\(\frac{\sum A_i}{n}\),得到第\(i\)堆還要丟掉/得到多少牌,要丟就直接丟到\(i+1\)堆,要得到就從\(i+1\)堆拿.直接這樣做就行.其實覺得這題還是挺巧妙的?在考場上可能沒那么容易想到\(QwQ\).

字符變換 搜索/字符串

直接\(bfs\),開個\(map\)記下搜過的就不要搜了.

正好學了下\(string\)的一些函數 ( 之前只知道\(length()\ QwQ\).用上函數就簡單多了,對了有個要注意的地方就是替換並不一定是替換第一個出現的位置,也要枚舉后面的.

string a,b;

a.insert(pos,b) //插入

a.erase(pos,n) //刪除[pos,pos+n-1]之間的字符

a.clear()

a.replace(pos,n,b) //將[pos,pos+n-1]之間的字符替換為b

注意replace里n的含義!不是[pos,n].

a.find(b) //從前往后找b第一次出現的位置並返回

a.find(b,pos) //從pos​開始找b第一次出現的位置並返回

//倒着找為rfind 沒找到返回的是string::npos

a.find_first_of(b);a.find_first_of(b,pos);找到與b中的任意一個元素就返回

a.find_last_of(b);...//倒着找

a.find_first_not_of(b);//找到不是b的任意一個元素並返回

a.substr(pos)//返回a里從pos到最后這段子

a.substr(pos1,pos2)//返回a中[pos1,pos2]這段子串

a=to_string(123)//將int轉為string

自由落體

物理題.計算出在小球們落到高度為\(k\)時小車的位置,和小球們落到高度\(0\)時小車的位置,在這兩個位置之間的小球就是能被接受到的小球.

\(upd:\)最后我還是選擇了\(O(n)\)枚舉判斷,感覺這樣判斷要簡單些不容易錯些.

\(*\)矩形覆蓋 搜索

直接枚舉矩形的左下角和右上角再\(check\)就可以了叭.矩形的端點並不一定是平面上的點吖!所以這個做法\(GG\)了.

直接搜哪些點在同一個矩形,判斷合法,最優性剪枝就行.

\(NOIp2001\ [4/4]\)


### 一元三次方程求解 枚舉/數學/二分

看根的范圍再看精度要求,枚舉枚舉就過了.

其實也可以用提示里的方法.因為根與根之間的絕對值\(\geq 1\).換言之,就是每個長度為\(1\)的區間內(除端點)至多只有一解.於是就可以猜想直接對於每個單位區間二分下答案就行.

然而我覺得很疑惑就是如果像二次函數那樣,可能\(f(l)>0,f(r)>0\),但\(x\in(l,r),f(x)=0\)這亞子就不能二分算了.被\(gql\)小朋友\(D:\)你真的不知道三次函數長什么亞子嘛??然后給我畫了個,確實不會有我說的那種情況.知道我數學有多差了叭.

數的划分 搜索

搜索入門題,記得可行性剪枝.

統計單詞個數

和[子串]有一絲相似?考慮\(dp\).

\(f_{i,j}\)表示前\(i\)個字符分了\(j\)段包含的最大單詞數.轉移顯然就是枚舉第\(i-1\)段的起始位置\(k\).

現在的問題就是如何計算一段\([k+1,i]\)之間有多少個單詞.這個可以\(O(n^3)\)預處理出\(g_{i,j}\)表示\([i,j]\)之間有多少個單詞.具體來說,預處理一個\(q_{i,0}\)指從位置\(i\)開始匹配有沒有單詞,\(q_{i,1}\)指從位置\(i\)開始匹配,匹配到的單詞的右界最少是多少.這樣預處理\(g_{i,j}\)就枚舉\(k\in[i,j]\),若\(q_{k,0}=1\)\(q_{k,1}\leq j\),就\(++g_{i,j}\).

\(Car\)的旅行路線

求出每個城市的第四個飛機場的坐標,然后直接按照題目要求連邊跑最短路就行.

\(WA\)了一發,我才知道原來給一個\(double\)賦值為\(-0\),輸出是\(-0.000\).

\(NOIp2000\ [4/4]\)


### 進制轉換 數學/進制

先只討論\(N\)為正數的情況.先將\(|r|\)進制下該數的表示求出來,再考慮怎么轉成\(-r\)進制.發現在奇數位,由於指數是偶數,所以可以先不動.假設第\(i(2|i)\)位上的值為\(x\),也就是這個數要加上\(|r|^{i-1}\cdot x\),其實就是要加上\(|r|^{i-1}\cdot (|r|+x-|r|)=|r|^i-|r|^{i-1}\cdot(|r|-x)\).於是將這一位變成\(|r|-x\),下一位加上\(1\).

那么\(N\)為負數怎么處理呢?先求出它絕對值的\(r\)進制表示,然后在奇數位和上面一樣變動就行.

乘積最大 \(dp\)

首先要預處理一個\(g_{i,j}\)表示\(i\)\(j\)組成的數是多少.然后就是典型的區間\(dp\)了,\(f_{i,j}\)表示前\(i\)個位置放了\(j\)個乘號的最大答案,轉移就枚舉第\(j\)的乘號的前一個位置\(k\)就成.

單詞接龍 搜索/字符串

去年覺得這題超級無敵巨難\(QwQ\).

預處理\(f_{i,j}\)表示\(i,j\)兩個單詞的中間重合部分的長度,如果是包含關系,則定義為\(0\).然后就可以直接開搜了,記錄當前字符串中最后一個單詞是啥,維護每個單詞用了多少個就行.

方格取數 \(dp\)

和傳紙條唯一不同的地方在於兩條路徑可以重復,只是重復部分只能算一次貢獻.

\(NOIp1999\ [4/4]\)


### 攔截導彈 $dp$/貪心

真的是很經典的題目吖.

要求最長不嚴格下降子序列的長度和把序列分成若干個不下降子序列的最少數量.

前者\(nlogn\)做法就設\(f_i\)表示當前最長序列的第\(i\)個導彈的高度,二分查找替換維護即可.后者就是個貪心,記下當前有的所有下降序列的末尾值,對於一個數\(x\),用比\(x\)大的最小的攔截它,如果都比它小,就開個新的.

回文數 模擬

入門題.我記得去年考過這題,然后因為某些原因我的程序沒進循環只判了第一個和最后一個相不相等,還獲得了\(90pts\)的好成績\(QwQ\).

旅行家的預算 貪心

先不考慮油箱大小的限制,那么先找到\(min\{P_i\}\),然后依次找前面比它大的最小的數...一直這樣找下去可以得到一個單調遞減的序列,每次只在這個序列里的加油站加油,加油的量就剛好加到到達下一個加油站.這樣顯然是最優的.

然而現在有一個油箱的限制,上面的做法可能不合法.然后我\(GG\)\(QwQ\).

從起點開始,在能走的范圍內找到\(P\)最小的,若這個\(P\)小於當前加油站的\(P\),那當前加油站就加油剛好能走到那個加油站,否則就直接加滿.注意下一個就到終點的情況要特判下.對了還要在最開始判掉無解.

郵票面值設計 搜索/\(dp\)

我前幾天才知道原來這題所有的算法都好假,數據是\(7\ 7\),\(7\ 8\)這樣的都跑不過.似乎只能跑過\(n+k\leq 9\)的所有數據.

還是講下這題的'假'搜索做法.

就直接搜選的\(n\)種郵票的面值,具體來說從小到大搜每個數,在搜當前數之前求下最大連續到了什么地方,則當前搜的數不能超過最大連續值\(+1\).

怎么求當前最大連續到什么地方了呢?發現這里就特別像去年的[貨幣系統],但是這里有貼\(k\)張郵票的限制.設\(f_i\)表示拼出\(i\)所需要的最小郵票數.完全背包轉移(注意確定上下界的問題)最后枚舉\(check\)即可.

\(NOIp1998\ [3/3]\)


### 拼數 字符串/排序/搜索

從前往后貪心地選取首位數字最大的,若首位數字相等就掃描后面的位置,選擇最大的.若兩個數\(x,y\), \(x\)的長度小於\(y\),在\(x\)的位數內和\(y\)都是相等的,就看下一個候選數的首字母與\(y\)\(x\)的位數+1的位置的關系.

\(QwQ\)發現上面的貪心真的很難想清楚,因為最后一個判斷可以嵌套然后我不會了.於是瞎寫了個搜索因為是\(NOIp\)數據所以\(AC\)辣.

講下題解做法,覺得好神奇啊,只要寫個\(cmp\)函數排下序就行,如下:

\(bool\ cmp(string\ a,string\ b)\{return\ a+b>b+a;\}\)

車站 找規律/遞推

設第二站上車的人數為\(x\),手推一下每一站上車人數減去下車人數的序列是:\(a,0,a,x,a+x,a+2x,2a+3x,3a+5x...\)\(f_i\)表示第\(i\)站上車人數減下車人數,發現\(f_i=f_{i-2}+f_{i-1},i\geq 5\).於是隨便推下就行.

\(*\)進制位 搜索

題目沒講不同字母代表的數不同差評.

好現在我們都知道字母代表的數不同了,那么一個行數列數為\(n+1\)的表代表的一定是\(n\)進制.可以反證法證明,就不證了.如果是考試可以猜結論\(QwQ\).

直接搜索每一個字母代表的是啥然后\(check\)就成,連剪枝都不要,因為搜索復雜度就是對的.


## $NOIp1997\ [1/1]$
### 棋盤問題 搜索

注意一個數不能填兩次.預處理下\(pri_i\)表示\(i\)是否為素數.然后直接開搜,先搜第一行和第一列,從小數搜到大數,第一個搜到的解就是最優解.(為啥?其實這個是我猜的\(QwQ\).但過了.

其實感覺上面很不對的亞子,最好還是搜完,加個最優性剪枝就成.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM