Tree-Based Dynamic Programming for Art Heist Optimization

The problem involves maximizing the number of paintings stolen from a binary tree-shaped museum within a time limit, where each node represents a room with specific traversal and theft costs.

Tree Construction

Each node is defined by two integers $w_1$ and $w_2$:

  • If $w_2 > 0$, the node is a leaf containing $w_2$ paintings, and entering it takes $2 \cdot w_1$ seconds.
  • If $w_2 = 0$, the node is internal and has exactly two children (left and right subtrees).

A recursive function builds the tree structure while assigning weights and values:

int build() {
    int w1, w2, cur = ++node_count;
    cin >> w1 >> w2;
    weight[cur] = w1 * 2;
    if (w2) {
        paintings[cur] = w2;
    } else {
        int left = build();
        children[cur].push_back(left);
        int right = build();
        children[cur].push_back(right);
    }
    return cur;
}

Dynamic Programming Setup

Let dp[u][t] represent the maximum number of paintings obtainable in subtree rooted at u using at most t seconds. The total available time is T - 1, as one second must remain to escape.

For leaf nodes:

  • Minimum time to enter: weight[u]
  • Each painting takes 5 seconds to steal
  • So, with i seconds allocated to this node, the number of stealable paintings is min((i - weight[u]) / 5, paintings[u])

For internal nodes, a tree-based grouped knapsack is applied:

  • Initialize dp[u][*] based on its own cost and potential loot
  • Then merge child contributions using nested loops that respect time constraints

Key DP transition:

for (int time = min(total_time[u], T - 1); time >= weight[u]; --time) {
    for (int child_time = 0; child_time <= min(subtree_time[child], time - weight[u]); ++child_time) {
        dp[u][time] = max(dp[u][time], dp[child][child_time] + dp[u][time - child_time]);
    }
}

Final Computation

After building the tree and running DFS from the root, the answer is simply dp[1][T - 1], representing the optimal number of paintings stolen from the entire museum within the allowed time.

Implementation Notes

  • Time complexity is manageable due to pruning via subtree size tracking
  • Memory usage is optimized by limiting DP table dimensions
  • Input/output redirection is used for file-based testing

Tags: tree Dynamic Programming KnapSack Recursion C++

Posted on Fri, 06 Nov 2026 16:43:39 +0000 by Sarok