背景:czy上課講了新知識,從未見到過,總結一下。
所謂動態dp,是在動態規劃的基礎上,需要維護一些修改操作的演算法。
這類題目分為如下三個步驟:(都是對於常係數齊次遞推問題)
1先不考慮修改,不考慮區間,直接列出整個區間的dp方程。這個是基礎,動態dp無論如何還是dp(這一步是一般是重點)
2.列出轉移矩陣。由於有很多修改操作,我們將資料集中在一起處理,還可以利用矩陣結合律,並且區間比較好提取,(找一段矩陣就好了),修改也方便。
3.線段樹維護矩陣。對於修改,我們就是在矩陣上進行修改,對於不同的題目,我們要用不同的修改方式,和記錄手段。但是都是線段樹乙個節點維護的是這個區間內矩陣的資訊。如矩陣乘積,矩陣和等等。線段樹的區間優勢,可以應對區間修改問題。
這裡,由於是單點修改,所以直接到葉子節點,修改後再pushup就可以了。
線段樹維護區間內矩陣乘積。
就是斐波那契數列。
這裡的可以原因是:提出b,因為矩陣右分配律,再提出乙個m^x,還是矩陣右分配律。注意這裡m^x,b是不能交換順序的。但是m^x放在求和的前邊乘,還是後邊乘是無所謂的。因為都是m
可以用左分配律,也可以用右分配律。
其實**不難想。
1.laz標記應當建乙個和t[4*n]一樣的laz[4*n],這樣,每個結構體只存乙個矩陣a,不但節省空間,而且內建函式的矩陣乘法還方便,因為無論如何都轉移到a矩陣,而不用考慮是a乘laz還是laz乘laz。
2.陣列越界了,被卡了很長時間。開a[3][3]就可以,沒有發現的原因是,c++本地編譯不會re,放到cf上就會出現奇怪答案,而且莫名有的地方陣列內的值就變了,比如說突然都變成0
3.注釋不要太多,以免掩蓋正解,導致把laz 下放注釋掉了。。。
本質不同:不一樣。長度不同,或者長度一樣對應位置數字不全一樣。
注意是子串行不是子串
注意,為什麼用f[i][0/1]?因為當最後一位不一樣時,這兩個子串行一定不一樣,所以f[i-1][0]和f[i-1][1]中的每乙個都是不一樣的。
並且,這還跟原陣列數值0/1掛鉤,很好聯絡上了。
加的乙個1是就取這一位,其實是之前每乙個都多了一位,就沒有了最初的長度為一的子串行。所以加上。
也就是說,區間矩陣乘積結果的矩陣可以直接進行翻轉,先翻再乘,和先乘再翻沒區別。
直接正常維護就好,加乙個rev標記。
POJ 1769線段樹維護dp
我們設dp i j 為做到第i個sort時候,最大值被移動到j需要轉移用的數目。dp i j dp i 1 j if ti j 即移動不到當前最大值 dp i j min dp i 1 j dp i 1 k si k ti 1 if ti j 即這個最大值包含在這個區間。我們發現dp值只與他前乙個有...
線段樹 維護序列
老師交給小可可乙個維護數列的任務,現在小可可希望你來幫他完成。有長為 n 的數列,不妨設為 a1,a2,an。有如下三種操作形式 把數列中的一段數全部乘乙個值 把數列中的一段數全部加乙個值 詢問數列中的一段數的和,由於答案可能很大,你只需輸出這個數模 p 的值。輸入格式 第一行兩個整數 n 和 p ...
線段樹 GD SGOI 公路維護
用線段樹維護區間沒有被損壞的路的最小值,最小值對應的下標,區間被損壞的路的個數。標記下穿的時候先傳add,再傳mark,傳add的時候minv,add,mark都要加上add o 傳mark的時候,minv,mark都要取最大。include include include include incl...