|
| 1 | +class Solution { |
| 2 | +public: |
| 3 | + int maxProfit(int n, vector<int>& present, vector<int>& future, vector<vector<int>>& hierarchy, int budget) { |
| 4 | + vector<vector<int>> tree(n); |
| 5 | + vector<int> in_degree(n, 0); |
| 6 | + for (auto &e : hierarchy) { |
| 7 | + int u = e[0] - 1; |
| 8 | + int v = e[1] - 1; |
| 9 | + tree[u].push_back(v); |
| 10 | + in_degree[v]++; |
| 11 | + } |
| 12 | + int root = 0; |
| 13 | + for (int i = 0; i < n; i++) { |
| 14 | + if (in_degree[i] == 0) { |
| 15 | + root = i; |
| 16 | + break; |
| 17 | + } |
| 18 | + } |
| 19 | + const long long INF = -(long long)1e15; |
| 20 | + vector<int> capability(n, 0); |
| 21 | + function<long long(int)> cap = [&](int u) -> long long { |
| 22 | + long long s = present[u]; |
| 23 | + for (int v : tree[u]) s += cap(v); |
| 24 | + capability[u] = (int)min<long long>(budget, s); |
| 25 | + return s; |
| 26 | + }; |
| 27 | + cap(root); |
| 28 | + |
| 29 | + vector<vector<long long>> dp0(n), dp1(n); |
| 30 | + |
| 31 | + auto merge = [&](const vector<long long>& a, const vector<long long>& b) -> vector<long long> { |
| 32 | + int len_a = (int)a.size() - 1; |
| 33 | + int len_b = (int)b.size() - 1; |
| 34 | + int total = min(budget, len_a + len_b); |
| 35 | + |
| 36 | + vector<long long> c(total + 1, INF); |
| 37 | + |
| 38 | + for (int i = 0; i <= min(len_a, total); i++) { |
| 39 | + long long ai = a[i]; |
| 40 | + if (ai == INF) |
| 41 | + continue; |
| 42 | + int maxj = min(len_b, total - i); |
| 43 | + for (int j = 0; j <= maxj; j++) { |
| 44 | + long long bj = b[j]; |
| 45 | + if (bj == INF) |
| 46 | + continue; |
| 47 | + long long val = ai + bj; |
| 48 | + if (val > c[i + j]) c[i + j] = val; |
| 49 | + } |
| 50 | + } |
| 51 | + return c; |
| 52 | + }; |
| 53 | + |
| 54 | + function<void(int)> dfs = [&](int u) { |
| 55 | + for (int v : tree[u]) |
| 56 | + dfs(v); |
| 57 | + |
| 58 | + vector<long long> skip(capability[u] + 1, INF); |
| 59 | + vector<long long> base(capability[u] + 1, INF); |
| 60 | + skip[0] = 0; |
| 61 | + base[0] = 0; |
| 62 | + |
| 63 | + for (int v : tree[u]) { |
| 64 | + skip = merge(skip, dp0[v]); |
| 65 | + base = merge(base, dp1[v]); |
| 66 | + } |
| 67 | + |
| 68 | + auto comp = [&](int parentBought) -> vector<long long> { |
| 69 | + int price = parentBought ? (present[u] / 2) : present[u]; |
| 70 | + long long profit = (long long)future[u] - price; |
| 71 | + vector<long long> maximize = skip; |
| 72 | + if (price <= capability[u]) { |
| 73 | + for (int b = price; b <= capability[u]; b++) { |
| 74 | + if (base[b - price] != INF) { |
| 75 | + long long can = base[b - price] + profit; |
| 76 | + if (can > maximize[b]) |
| 77 | + maximize[b] = can; |
| 78 | + } |
| 79 | + } |
| 80 | + } |
| 81 | + return maximize; |
| 82 | + }; |
| 83 | + |
| 84 | + dp0[u] = comp(0); |
| 85 | + dp1[u] = comp(1); |
| 86 | + }; |
| 87 | + |
| 88 | + dfs(root); |
| 89 | + return *max_element(dp0[root].begin(), dp0[root].end()); |
| 90 | + } |
| 91 | +}; |
0 commit comments