leetcode

Leetcode Solutions (0x6A73)
git clone https://git.pngu.org/leetcode
Log | Files | Refs | Submodules | README

commit afdb1453746fb454433383ea74f959eb4ce2f7a1
parent 6a7c91c564b83a756b66ab223861890fb1334410
Author: Jack Sangdahl <jack@pngu.org>
Date:   Mon, 15 Dec 2025 20:48:52 -0700

3562. maximum profit from trading stocks with discounts

Diffstat:
Amax_profit_trade_stocks.c | 196+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amax_profit_trade_stocks.py | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 289 insertions(+), 0 deletions(-)

diff --git a/max_profit_trade_stocks.c b/max_profit_trade_stocks.c @@ -0,0 +1,196 @@ +// 3562. Maximum Profit from Trading Stocks with Discounts +#include "leetcode.h" + +/* + * you are given an integer 'n' representing the number of employees in a + * company. each employee is assign a unique id from 1 to 'n', and employee 1 is + * the ceo. you are given two integers arrays 'present' and 'future', each of + * length 'n', where 'present[i]' represents the current price at which the i'th + * employee can buy stock today. 'future[i]' represents the expected price at + * which the i'th employee can sell the stock tomorrow. the company's hierarchy + * is represented by a 2d integer array 'hierarchy', where 'hierarchy[i] = [u_i, + * v_i]' means that employee 'u_i' is the direct boss of employee can buy their + * stock at half the original price. return the maximum profit that can be + * achieve without exceeding the budget. + */ + +struct data { + int *arr; + int size; + int capacity; +}; + +void array_init(struct data *obj) { + obj->capacity = 10; + obj->size = 0; + obj->arr = (int *)malloc(obj->capacity * sizeof(int)); +} + +void array_push(struct data *obj, int val) { + if (obj->size >= obj->capacity) { + obj->capacity *= 2; + obj->arr = (int *)realloc(obj->arr, obj->capacity * sizeof(int)); + } + obj->arr[obj->size++] = val; +} + +void array_free(struct data *obj) { free(obj->arr); } + +int **children, *children_cnt, *present, *future, global_budget, ***memo; + +void dfs(int node, int parent_bought, int **dp_out, int *dp_size) { + if (memo[node][parent_bought]) { + *dp_out = memo[node][parent_bought]; + *dp_size = (global_budget + 1) * 2; + return; + } + int *dp = (int *)malloc((global_budget + 1) * sizeof(int)); + for (int i = 0; i <= global_budget; i++) + dp[i] = -1; + dp[0] = 0; + int cost = parent_bought ? present[node - 1] / 2 : present[node - 1]; + int profit = future[node - 1] - cost; + if (!children_cnt[node]) { + if (cost <= global_budget) + dp[cost] = profit; + memo[node][parent_bought] = dp; + *dp_out = dp; + *dp_size = global_budget + 1; + return; + } + int **child_dp_not_bought = + (int **)malloc(children_cnt[node] * sizeof(int *)); + int *child_dp_not_bought_size = + (int *)malloc(children_cnt[node] * sizeof(int)); + for (int i = 0; i < children_cnt[node]; i++) + dfs(children[node][i], 0, &child_dp_not_bought[i], + &child_dp_not_bought_size[i]); + int **child_dp_bought = (int **)malloc(children_cnt[node] * sizeof(int *)); + int *child_dp_bought_size = (int *)malloc(children_cnt[node] * sizeof(int)); + for (int i = 0; i < children_cnt[node]; i++) + dfs(children[node][i], 1, &child_dp_bought[i], &child_dp_bought_size[i]); + int *curr = (int *)malloc((global_budget + 1) * sizeof(int)); + for (int i = 0; i <= global_budget; i++) + curr[i] = -1; + curr[0] = 0; + for (int i = 0; i < children_cnt[node]; i++) { + int *next = (int *)malloc((global_budget + 1) * sizeof(int)); + for (int j = 0; j <= global_budget; j++) + next[j] = -1; + for (int b1 = 0; b1 <= global_budget; b1++) { + if (curr[b1] == -1) + continue; + for (int b2 = 0; b2 <= global_budget - b1; b2++) { + if (child_dp_not_bought[i][b2] == -1) + continue; + int total_budget = b1 + b2, + total_profit = curr[b1] + child_dp_not_bought[i][b2]; + if (next[total_budget] < total_profit) + next[total_budget] = total_profit; + } + } + free(curr); + curr = next; + } + for (int b = 0; b <= global_budget; b++) + if (curr[b] > dp[b]) + dp[b] = curr[b]; + if (cost <= global_budget) { + int *buying = (int *)malloc((global_budget + 1) * sizeof(int)); + for (int i = 0; i <= global_budget; i++) + buying[i] = -1; + buying[0] = 0; + for (int i = 0; i < children_cnt[node]; i++) { + int *next = (int *)malloc((global_budget + 1) * sizeof(int)); + for (int j = 0; j <= global_budget; j++) + next[j] = -1; + for (int b1 = 0; b1 <= global_budget - cost; b1++) { + if (buying[b1] == -1) + continue; + for (int b2 = 0; b2 <= global_budget - cost - b1; b2++) { + if (child_dp_bought[i][b2] == -1) + continue; + int total_budget = b1 + b2, + total_profit = buying[b1] + child_dp_bought[i][b2]; + if (next[total_budget] < total_profit) + next[total_budget] = total_profit; + } + } + free(buying); + buying = next; + } + for (int b = 0; b <= global_budget - cost; b++) { + if (buying[b] != -1) { + int total_budget = b + cost, total_profit = buying[b] + profit; + if (dp[total_budget] < total_profit) + dp[total_budget] = total_profit; + } + } + free(buying); + } + free(curr); + free(child_dp_not_bought); + free(child_dp_not_bought_size); + free(child_dp_bought); + free(child_dp_bought_size); + memo[node][parent_bought] = dp; + *dp_out = dp; + *dp_size = global_budget + 1; +} + +int maxProfit(int n, int *presentArr, int presentSize, int *futureArr, + int futureSize, int **hierarchy, int hierarchySize, + int *hierarchyColSize, int budget) { + present = presentArr; + future = futureArr; + global_budget = budget; + children = (int **)malloc((n + 1) * sizeof(int *)); + children_cnt = (int *)calloc(n + 1, sizeof(int)); + for (int i = 0; i <= n; i++) + children[i] = (int *)malloc(n * sizeof(int)); + for (int i = 0; i < hierarchySize; i++) { + int parent = hierarchy[i][0]; + int child = hierarchy[i][1]; + children[parent][children_cnt[parent]++] = child; + } + memo = (int ***)malloc((n + 1) * sizeof(int **)); + for (int i = 0; i <= n; i++) + memo[i] = (int **)calloc(2, sizeof(int *)); + int *dp, dp_size, max_profit = 0; + dfs(1, 0, &dp, &dp_size); + for (int b = 0; b <= global_budget; b++) + if (dp[b] > max_profit) + max_profit = dp[b]; + for (int i = 0; i <= n; i++) { + for (int j = 0; j < 2; j++) + if (memo[i][j] != NULL) + free(memo[i][j]); + free(memo[i]); + free(children[i]); + } + free(memo); + free(children); + free(children_cnt); + return max_profit; +} + +int main() { + int p1[] = {1, 2}, f1[] = {4, 3}, h1i[1][2] = {{1, 2}}; + int p2[] = {3, 4}, f2[] = {5, 8}, h2i[1][2] = {{1, 2}}; + int p3[] = {4, 6, 8}, f3[] = {7, 9, 11}, h3i[2][2] = {{1, 2}, {1, 3}}; + struct two_d_arr *h1 = + two_d_arr_init(ARRAY_SIZE(h1i), ARRAY_SIZE(h1i[0]), h1i); + struct two_d_arr *h2 = + two_d_arr_init(ARRAY_SIZE(h2i), ARRAY_SIZE(h2i[0]), h2i); + struct two_d_arr *h3 = + two_d_arr_init(ARRAY_SIZE(h3i), ARRAY_SIZE(h3i[0]), h3i); + printf("%d\n", maxProfit(2, p1, ARRAY_SIZE(p1), f1, ARRAY_SIZE(f1), h1->arr, + h1->row_size, h1->col_size, 3)); // expect: 5 + printf("%d\n", maxProfit(2, p2, ARRAY_SIZE(p2), f2, ARRAY_SIZE(f2), h2->arr, + h2->row_size, h2->col_size, 4)); // expect: 4 + printf("%d\n", maxProfit(3, p3, ARRAY_SIZE(p3), f3, ARRAY_SIZE(f3), h3->arr, + h3->row_size, h3->col_size, 10)); // expect: 10 + two_d_arr_free(h1); + two_d_arr_free(h2); + two_d_arr_free(h3); +} diff --git a/max_profit_trade_stocks.py b/max_profit_trade_stocks.py @@ -0,0 +1,93 @@ +# 3562. Maximum Profit from Trading Stocks with Discounts + +""" +you are given an integer 'n' representing the number of employees in a +company. each employee is assign a unique id from 1 to 'n', and employee 1 is +the ceo. you are given two integers arrays 'present' and 'future', each of +length 'n', where 'present[i]' represents the current price at which the i'th +employee can buy stock today. 'future[i]' represents the expected price at +which the i'th employee can sell the stock tomorrow. the company's hierarchy +is represented by a 2d integer array 'hierarchy', where 'hierarchy[i] = [u_i, +v_i]' means that employee 'u_i' is the direct boss of employee can buy their +stock at half the original price. return the maximum profit that can be +achieve without exceeding the budget. +""" + + +class Solution(object): + def maxProfit(self, n, present, future, hierarchy, budget): + """ + :type n: int + :type present: List[int] + :type future: List[int] + :type hierarchy: List[List[int]] + :type budget: int + :rtype: int + """ + tree = [[] for _ in range(n)] + for u, v in hierarchy: + tree[u - 1].append(v - 1) + dp = [[[0] * (budget + 1) for _ in range(2)] for _ in range(n)] + self.dfs(0, present, future, tree, dp, budget) + return max(dp[0][0]) + + def dfs(self, u, present, future, tree, dp, budget): + children = tree[u] + child_dps = [] + for v in children: + self.dfs(v, present, future, tree, dp, budget) + child_dps.append((dp[v][0], dp[v][1])) + for parentBought in range(2): + price = present[u] // 2 if parentBought else present[u] + profit = future[u] - price + base = [0] * (budget + 1) + for c0, _ in child_dps: + next_base = [0] * (budget + 1) + for b in range(budget + 1): + if base[b] == 0 and b != 0: + continue + for k in range(budget - b + 1): + next_base[b + k] = max(next_base[b + k], base[b] + c0[k]) + base = next_base + curr = base[:] + if price <= budget: + base = [0] * (budget + 1) + for _, c1 in child_dps: + next_base = [0] * (budget + 1) + for b in range(budget + 1): + if base[b] == 0 and b != 0: + continue + for k in range(budget - b + 1): + next_base[b + k] = max(next_base[b + k], base[b] + c1[k]) + base = next_base + for b in range(price, budget + 1): + curr[b] = max(curr[b], base[b - price] + profit) + dp[u][parentBought] = curr + + +if __name__ == "__main__": + obj = Solution() + print( + obj.maxProfit(n=2, present=[1, 2], future=[4, 3], hierarchy=[[1, 2]], budget=3) + ) + print( + obj.maxProfit(n=2, present=[3, 4], future=[5, 8], hierarchy=[[1, 2]], budget=4) + ) + print( + obj.maxProfit( + n=3, + present=[4, 6, 8], + future=[7, 9, 11], + hierarchy=[[1, 2], [1, 3]], + budget=10, + ) + ) + print( + obj.maxProfit( + n=3, + present=[5, 2, 3], + future=[8, 5, 6], + hierarchy=[[1, 2], [2, 3]], + budget=7, + ) + )