簡寫,筆錄,不寫太多。
概要:
給出若干物品,對於每個物品的投入x,會得到一個特定回報f(x)
已知總投入爲M元,求能得到的最大回報N元。
方程即爲:dp(x) = max{ dp(x),dp(a) + l(x-a)} (A式) .這是對於線性數據而言的,沒有依賴關係。
在樹上學習到了一個很厲害的寫法:
一般來說,如果是要把 A式 用在樹規上, 時間大概在 O(N^3)
轉換一個巧妙地表達方法即可壓縮到 O(N^2)
描述:
dfs(int root , int m) //m表示總投入
對於每一個子節點:
f[subtree][i] <- f[root][i] i=0,1,2....m-1
dfs(subtree,i);
f[root][i] = f[subtree][i-1] + value[i]; i = 0,1,2.....m
講白,就是每次處理子節點,先把root的值賦進去,然後在進行遞歸搜索,爲什麼這樣是有用的?
我們知道,如果反覆使用A式求解的話 , 事實上每次動規都沒有和父節點聯繫起來,而是在所有數據處理完了以後,再進行計算。
這就浪費了大量的時間。
把父節點的值回代,使得父節點成爲整個動態規劃的一部分。因爲父節點的值對於子樹的計算過程沒有絲毫影響,計算完畢後,直接更新父節點的值。有點類似於線段樹的“有了標記要值還有什麼用”(哈哈哈哈)
//注
第一個循環到m-1 ,因爲如果你要考慮使用這個節點,本身也需要使用,那麼能夠分配給這個節點的子樹的投入只有m-1個了