Tree Backpack summary

concept

Tree backpack, that is, choose a tree that contains the root of a communication block, or backpack dependencies (selected parent to choose the child), or need to know the sub-tree for each point of the selected number ......
In general, we have two ways:

First, based dfs merger:

We set \ (dp (i, j) \) represents the j-th node selected in the i sub-state.
When the transfer, dfs first child node, then the node sequentially combined handle, combined two each.
I.e. enumeration \ (A, B \) , with \ (dp (i, a) \) and \ (dp (son, b) \) combination \ (F (A + B) \) , each merged , assigned to the f dp.

The following analysis of time complexity:

1, item 1 of size, there is no limit:

(Fake code:

void Tree_Dp(int p)
{
    size[p]=1;
    each(x,son[p])
    {
        Tree_Dp(x);
        for(int i=0;i<=size[p];++i)
            for(int j=0;j<=size[x];++j)
                update dp[p][i+j];
        size[p]+=size[x];
    }
}

Time complexity is \ (O (^ n-2) \) .
Consider the double loop, each point can be seen as two separately enumeration sub-tree. Can be found, point \ ((U, V) \) , only the \ (Tree_Dp (lca (u, v)) \) at is taken into account, so complexity is \ (O (n ^ 2) \) .

2, there are items Size:

This complexity is not clear to me, it can be snapped into the \ (O (the n-^ 3) \) , however, when the data is random can beat 8000,1s of.

3, the article size is 1, k is limited.

(Fake code:

void dfs(int u, int fu) {
    int si = 0;
    for (int i = fr[u]; i != -1; i = ne[i]) {
        if (v[i] != fu) 
            dfs(v[i], u);
    }
    for (int i = fr[u]; i != -1; i = ne[i]) {
        if (v[i] == fu) continue;
        int rt = sz[v[i]];
        for (int a = 0; a <= min(si, k); a++) {
            for (int b = 0; b <= min(rt, k - a); b++) {
                   //转移dp
            }
        }
        si += rt;
    sz[u] = si + 1;
}

This algorithm initially think it is \ (O (nk ^ 2) \) is actually \ (O (nk) \) is.

Complexity Proof:

  1. The complexity of tree normal backpack \ (O (^ n-2) \) , at most equal to less than k is generated \ (n / k * k ^ 2 \) complexity.
  2. K and k is greater than greater than once combined, are combined on the k increases, up to n / k times, generating up \ (n / k * k ^ 2 \) complexity.
  3. K is greater than the combined time of less than equal to k, and each is incorporated a maximum of less than or equal to k, it is \ (S_1 * + n-n-n-* * S_2 S_M + ... + \) , but also \ (NK \) .

There is an understanding:

Dfs sequence according to the tree becomes sequence.
Then, take the subtree enumeration of x, it can be understood as (rear) take the first x dfs sequence.
While merging, that the x after taking a subtree, before taking another one of y. \ ((X + Y \ Leq K) \) . This may be combined into a long interval of x + y.
This is actually no greater than the length of the substring k, up to the nk.
However, because there are circumstances take 0, so do the actual title, about the constant 2. But that ignores the constant can.

Two, dp dfs the sequence:

Dfs order according to consider:
we set \ (DP (i, j) \) represents consideration of the i-th, j is the state remaining capacity is:
There are two transfer:
1, i is not selected, then the subtree are not selected from i proceeds to \ (DP (Size_i + I, J) \) .
2, selected from the group i, then according to the order considering a dfs proceeds to \ (DP (I +. 1, JW) + V \) .
Obviously correctness.

Code

(not mine)

void dfs(int u)
{
    int tmp=tot;
    for(int i=head[u];i;i=indexx[i].next)
    {
        int v=indexx[i].to;
        dfs(v);
    }
    cost[++tot]=temp[u];
    f[tot]=tmp;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&v[i],&p[i],&q[i]);
        temp[i]=banana(v[i],v[i]*p[i]);
        init(q[i],i);
    }
    dfs(0);
    for(int i=1;i<=m;i++)
    {
        for(int j=0;j<=n;j++)
        {
            if(j>=cost[i].v)
                dp[i][j]=max(dp[f[i]][j],dp[i-1][j-cost[i].v]+cost[i].w);
            else
                dp[i][j]=dp[f[i]][j];//fi就是i-size(i)
        }
    }
    printf("%d\n",dp[m][n]);
}

Time complexity analysis

This comparison clearly, n-points, m capacity limitations (not then m = n), a state where \ (nm \) a transfer consideration \ (O (. 1) \) , complexity \ (O (nm) \) .
Further, this method is better, and less constant.

Example 1


Title Description

Jinming I am very happy, the family purchased a new house on the key essentials, the new room has a Jinming own and with very spacious rooms. He became even more pleased that my mother yesterday and said to him: "You need room which items to buy, how layout, you have the final say, as long as more than N Ji dollars on the line." Today morning, Jin Ming started doing the budget, and he wanted to buy the items into two categories: main parts is not attachment, the attachment is an example of some of the main pieces are not subordinate to an attachment member, the table below:

Primary attachment member

Computer printers, scanners

Bookcase books

Desk lamp, stationery

No work chair

If you buy classified as accessory items, you must first buy a piece of the attachment belongs. Each main member can have many attachments. Accessories may be subordinate to their own accessories. Jinming want to buy a lot of things, certainly more than the limit N mother yuan. Thus, each item he specifies a degree of importance, and the like is divided into 5: represents an integer 1-5, fifth, etc. most important. He also found the price of each item (all in less than 10 yuan) from the Internet. He wants without exceeding N element (element may be equal to N), so that the sum of the price of each item of the product of the maximum unimportant. Provided the j items price V [j], the degree of importance of W [j], were selected k items, numbers followed by j1, j2, ..., jk, then the required sum is: v [j1] × w [j1] + v [ j2] × w [j2] + ... + v [jk] × w [jk] Please help Jinming designed to meet the requirements of a shopping list.
Input Format

At line 1, two positive integers, separated by a space:

N, m (where N (<8000) represents the total amount of money, m (<8000) to a desired number of purchase items.) From the second line to the first line m + 1, j-th row gives the number j- basic data items 1, each row has three non-negative integers :: v, p, q (where v represents the price of the item (v <10), p indicates the degree of importance of the item (1-5), q indicates that the article is a master or member attachment. If q = 0, represents the main element of the article, if q> 0, indicating that the article is attachment, q is the number of member belongs (q <j-1))
output format

A positive integer, the maximum value of the sum exceeds the total price Ji unimportant items of money of the product.


This is apparently the tree backpack.
If the method 1, since the influence of the size of the article, can be snapped into the \ (O (nm ^ 2) \) .
However, the second method is \ (O (nm) \) , and soon, okay write.

(Differs greatly).

Example 2

[JSOI2018] dive into the action
this question, because I want to know information about parent-child relationships (for example: whether the parent node selection, etc.), the second method can not be used.

Example 3

[SDOI2017] apple
this problem somewhat like Example 1, except that a plurality of articles, after transfection into dfs sequence, to optimize the queue monotone complexity \ (O (NK) \) . If the method of least 1 \ (O (NK ^ 2) \) .

Summarized below:

Method One:
you can know the exact circumstances of each point can be used with an ordinary tree dp (because, after all, is in the trees).
However, higher complexity (since merged backpack is very slow).

Method two:
the complexity of the lower (as no merge backpack, corresponding to successively added).
However, it can not know the exact circumstances of each point (because it is in the sequence), some questions can not be used.

Guess you like

Origin www.cnblogs.com/lnzwz/p/11519977.html