筆記:《挑戰程式設計競賽(第2版)》(2)
Page 134 : Millionaire
這個題,以我的智商,一開始沒有很好的理解他的題解。之後看程式碼就毀了,程式碼裡第一重迴圈示意的方向是反的,雖然只要輪數對了就好,不過這樣程式碼阻礙理解題解,我看了好久才反應過來。
程式碼倒數第三行
int i = (ll)X * n / 100000;
中的
X * n / 10000000
其實是
X / (1000000 / n)
也就是將100000分成`n + 1(n = 2 ^ m)`份,就可以得出X在其中是哪一份(的索引)。
接下來的一個細節問題是搜尋的邊界,程式碼裡有
int jub = min(i, n - i)
這裡jub就代表了當前錢數的投注(搜尋)區間[i - jub, i + jub]
。
取i和n - i
中的小值。
前一個很好理解:不能投注比自己當前錢數還多的錢。
不過後一個就不太明顯了。
首先知道動態規劃陣列(prv,nxt)的右邊界(即下標n)代表了錢數超出1000000的所有部分。
邏輯上,此時i + jub == n
對應多個i - jub
,即可以投注多種錢數區間,贏了以後都轉移到下標n,而輸了則轉移到對應區間。
所以右邊界乍看上去似乎不太合適,沒有列舉所有可能的輸錢區間(對應於i + jub > n
的jub)。
這裡給出一個解釋:
容易理解,整個動態規劃陣列是單調非嚴格遞增的(持有的錢多更容易贏)。
所以對於剛才所說的多個i - jub
對應一個i + jub == n
。
prv[i + jub]
此時是定值。
其實只需要看最大的一個 prv[i - jub]
。當jub取n - i
時,有n關於i的對稱點(即i - jub
的最大值)i - (n - i)
。
Page 181 : 樹狀陣列的區間操作
樹狀陣列可以支援高效地查詢和修改數列的字首和。不過如果加入區間修改,問題就變複雜了。顯然不能對區間逐個修改。
考慮對於僅在一個區間[l, r)
上做了修改(增加x)的情況,此時,可以發現,對於l之前的部分,字首和不變。對於r之後的部分,字首和增加了一個常數(r - l) * x
。
關鍵是對於[l, r)
之間的部分,字首和的增加量是x的函式,對於l <= j < r
,有(j - l) * x
。
擴充到多個區間時,我們有多個xi分別對應[li, ri)
區間。
讓我們化簡一下問題,既然對於查詢在[li, ri)
之外的部分,我們都可以用常數表示其增量。
那麼我們就關注對於特定的位置a,查詢[0, a)
的和,我們只關注那些使li <= a < ri
的[li, ri)
。
現在的問題是如何高效地表示
(a - li) * xi
如果我們將所有的li向左延伸到0(對應地,需要減去常量li * xi
),就有
a * xi
問題變成了如何高效地求解∑xi
。
答案可以是另一個樹狀陣列。
整理一下
有一個樹狀陣列bit0, 我們希望對其實施區間修改操作。
為此,需要引入另一個樹狀陣列bit1。
對bit0上一個區間[l, r)
增加x可以表示為
- 在bit0的l處增加
-(l * x)
- 在bit1的l處增加x。
當查詢位置a越過了r時,我們還要撤銷x的效果
- 在bit1的r處增加一個
-x
。
這樣就撤銷了位置相關的修改,但要在bit0上加上常量增量,之前已經增加過-(l * x)
(實際上是減少的意思)
- 在bit0的r處增加一個
r * x
更一般地,如果操作得到的結果可以用i的n次多項式表示,那麼就可以使用n + 1個樹狀陣列來進行維護了。
這裡還是不明白,i的1次多項式的實際意義可以是區間修改,那麼i的更高次多項式又可以具有怎樣的意義呢?
Page 194 : 計算DAG的最短路
計算DAG的最短路不需要使用Dijkstra演算法,可以簡單地通過DP求解。
對於這句話我的理解如下:
考慮Dijkstra演算法所能求解範圍——邊權為正的圖,DAG與其的區別在於前者可以有環路。
Dijkstra演算法處理環的方法是應用問題的貪心性,每次選取從起點出發最近抵達的點,這個點不可能有其它更短的路徑了。
DAG因為不存在環路,只要求解了一個點的所有前驅(沒有環才有這個定義)的最短路,自然就可以求解這個點最短路。
所以對點的選取順序要求變弱,只要按照(任一)拓撲序選點求行了。
另外,根據上下文,這裡可能想強調的是具有規則分層結構的DAG,對於這種DAG可以容易地寫出動態規劃演算法。比如本題的圖就很規則,按照集合的大小(遞減)分出不同層次,逐層求解。
相關文章
- 筆記:《挑戰程式設計競賽(第2版)》(3)筆記程式設計
- 筆記:《挑戰程式設計競賽(第2版)》(1)筆記程式設計
- 《挑戰程式設計競賽(第2版)》譯者訪談問題有獎徵集程式設計
- 挑戰程式設計競賽選讀-選擇排序程式設計排序
- 雲原生程式設計挑戰賽火熱開賽,51 萬獎金等你來挑戰!程式設計
- Android程式設計權威指南(第2版)—第14章挑戰練習Android程式設計
- Android程式設計權威指南(第2版)—第15章挑戰練習Android程式設計
- Android程式設計權威指南(第2版)—第12章挑戰練習Android程式設計
- 程式設計挑戰程式設計
- 【筆記】《JavaScript高階程式設計(第3版)》(2)筆記JavaScript程式設計
- 某大學程式設計競賽程式設計
- 第 10 屆 CCPC 中國大學生程式設計競賽濟南站 遊記程式設計
- 《實戰 Java 高併發程式設計》筆記——第2章 Java 並行程式基礎(二)Java程式設計筆記並行行程
- ACM-ICPC世界冠軍教你如何備戰程式設計競賽ACM程式設計
- 記微軟OpenHack機器學習挑戰賽微軟機器學習
- 「 C++挑戰賽 」下週開始,最特別的程式設計題目等你挑戰!C++程式設計
- JavaScript DOM 程式設計藝術(第2版) 讀書筆記JavaScript程式設計筆記
- 【週週有獎】雲原生程式設計挑戰賽“邊緣容器”賽道邀你來戰!程式設計
- 第15屆浙江省大學生程式設計競賽D題程式設計
- pythonchallenge 挑戰筆記Python筆記
- 牛客程式設計巔峰賽S2第11場程式設計
- html/css/javascript 程式設計挑戰HTMLCSSJavaScript程式設計
- 程式設計師的最大挑戰程式設計師
- 官宣!第三屆雲原生程式設計挑戰賽正式啟動!程式設計
- [補題] 第 45 屆國際大學生程式設計競賽(ICPC)亞洲區域賽(上海)程式設計
- 程式設計競賽中讀檔案技能程式設計
- 2013程式設計之美全國挑戰賽資格賽之傳話遊戲薦程式設計遊戲
- Java高階程式設計筆記 • 【第4章 網路程式設計】Java程式設計筆記
- oracle程式設計藝術筆記-2Oracle程式設計筆記
- 雲原生程式設計挑戰賽 Less is more - Serverless 創新應用賽火熱開啟中程式設計Server
- 100+隊伍逐鹿大獎,創新程式設計挑戰賽秋季賽圓滿落幕程式設計
- 給黑客們的程式設計挑戰黑客程式設計
- [題解][2021-2022年度國際大學生程式設計競賽第10屆陝西省程式設計競賽] Type The Strings程式設計
- 勝因沙龍 - 程式設計競賽(持續更新)程式設計
- 紹興市大學生程式設計競賽程式設計
- 2024端午鋁紫程式設計競賽程式設計
- 【AI競賽】TinyMind漢字書法識別挑戰賽開始報名啦!!AI
- 伯樂線上程式設計挑戰第 0 期 - 來電轉駁系統程式設計