STL 練習題,當 S 為 set or multiset 時,使用 for(auto it: S)
,會依序由小到大輸出。
定義 為放完 的方法數。
觀察一下,如果只要放滿第 直排的話,我們只有下面 種放法。
如果是第 種放法,那可以得知放完 的方法數為 。
如果是第 種放法,放完 的方法數就是 。
因此我們就得到了式子 。
,
根據題目我們可以知道答案會根據步數以及起點和終點的不同而不同,所以我們可以使用一個陣列 dp[t][u][v]
來維護從 u 到 v 走 t 步能得到的最大值。
假設現在已經知道從 u->v
的最大值了,接著需要尋找有沒有一個 k
點可以讓 u->k->v
的值更大,這樣我們就可以推導出轉移式為 dp[t][u][v]=max(dp[t][u][v], dp[t-1][u][k]*dp[1][k][v])
,最後只需要判斷 ,有沒有成立就行,如果有的話就代表得到答案了,否則就 繼續尋找有沒有,直到通通跑完還是得不到解才輸出 go back go back
。
需要注意的是雖然根據題目定義是可以來回穿越的,但這行為是沒有意義的,只要第一次穿越沒有超過 接下來的穿越也不會超過,只會越來越小。
定義 ,
為放滿 的方法數,
為放滿 以及第 直排的上面的格子,
和 差不多,只是換成下面的格子。
其實 和 一直都會一樣,所以實作上可以合併成一個變數就好
如果只考慮放滿第 個直排,則只有以下 種放法:
因此 就可以寫成
。
而 和 也可以用類似的方法得到式子。
,
,
大家可以試著將上面的解法改為一維的 dp。
從第三週教材延伸, 表示以 為結尾的最大區間和
假設 為乘上 的區間
那麼從左至右遍歷 結尾的最大區間和:
由於無法確定最佳的 為何,
考慮計算 時尚未使用及已經使用乘上 後的區間和的決策
則可以拆成三種定義狀態:
狀態示意圖(?)
狀態轉移為:
其中邊界
實作上,對於 轉移只需用到 時的狀態,可利用滾動陣列將用不到的空間省下