演算法
(區間dp,二叉樹的遍歷)
狀態表示:\(f[i][j]\) 表示中序遍歷是 \(w[i~j]\) 的所有二叉樹的得分的最大值。
狀態計算:\(f[i][j] = max(f[i][k - 1] * f[k + 1][j] + w[k])\),即將\(f[i][j]\)表示
的二叉樹集合按根節點分類,則根節點在 k 時的最大得分即
為\(f[i][k - 1] * f[k + 1][j] + w[k]\)則\(f[i][j]\)即為遍歷 k 所取到的最大值。
在計算每個狀態的過程中,記錄每個區間的最大值所對應的根節點編號。
那麼最後就可以通過dfs求出最大加分二叉樹的前序遍歷了。
時間複雜度狀態總數是 \(o(n^2)\),計算每個狀態需要 \(o(n)\)的計算量,因此總時間複雜度是\(o(n^3)\)。
#include #include #include #include using namespace std;
typedef pairpii;
const int n = 50;
int n;
int w[n];
unsigned f[n][n];
int root[n][n];
void dfs(int l, int r)
int main()}}
printf("%d\n", f[1][n]);
dfs(1, n);
puts("");
return 0;
}
區間DP 加分二叉樹
題目 設乙個n個節點的二叉樹tree的中序遍歷為 1,2,3,n 其中數字1,2,3,n為節點編號。每個節點都有乙個分數 均為正整數 記第i個節點的分數為 d i tree及它的每個子樹都有乙個加分,任一棵子樹subtree 也包含tree本身 的加分計算方法如下 subtree的左子樹的加分 su...
加分二叉樹(區間dp 樹的遍歷)
題目鏈結 思路 這題明確說明樹的中序遍歷是1 2 3 n 所以我們任取其中一段子串行,一定滿足某顆子樹的中序遍歷 故而可以考慮用區間dp 邊界就是dp i i 另外用root i j 存i到j這段的根節點。有個坑點,列舉乙個長度大於1的區間上的根的時候,根節點不可以出現在最右端,因為中序遍歷根節點不...
加分二叉樹 區間DP,記憶化搜尋)
設乙個n個節點的二叉樹tree的中序遍歷為 1,2,3,n 其中數字1,2,3,n為節點編號。每個節點都有乙個分數 均為正整數 記第i個節點的分數為didi,tree及它的每個子樹都有乙個加分,任一棵子樹subtree 也包含tree本身 的加分計算方法如下 subtree的左子樹的加分 subtr...