泛化揹包問題

簡寫,筆錄,不寫太多。

  

概要:

        給出若干物品,對於每個物品的投入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個了 


    

        

發佈了52 篇原創文章 · 獲贊 7 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章