1. 程式人生 > >樹形背包!

樹形背包!

png 。。 += img 復雜 ++ 狀態 head 樹形

樹形背包的樸(wu)素(nao)操作的時間復雜度是n^3的,設有n個節點,背包容量為m(和n大小在一個級別上)

以01背包舉例:

void dfs(int u){
    for(int i=head[u];i!=-1;i=edge[i].nxt){
        int v=edge[i].to;
        dfs(v);
        for(int i=m;i>=0;i--){
            int tmp=0;
            for(int j=0;j<=i;j++){
                tmp=max(tmp,dp[u][j]+dp[v][i-j]);
            }
            dp[u][i]
=tmp; } } }

上面的枚舉顯然是n^3的。。。

然而上面這種方法枚舉到了很多還沒有被轉移過的無效狀態,所以可以用siz數組優化。。。

代碼如下:

void dfs(int u){
    for(int i=head[u];i!=-1;i=edge[i].nxt){
        int v=edge[i].to;
        dfs(v);
        for(int j=siz[u];j>=0;j--){
            int tmp=0;
            for(int k=0;k<=siz[v];k++){
                tmp
=max(tmp,dp[u][j]+dp[v][k]) } dp[u][j+k]=tmp; } siz[u]+=siz[e]; } }

於是時間復雜度就降至n^2。。。

技術分享圖片

證明如下:

對於每個點對(i,j),

只有在更新到LCA的時候才會出現一次,

所以對於每個點都是一個n,

總體就是n^2。。。

就醬。。。

技術分享圖片

樹形背包!