1. 解题思路
这一题没有搞定,思路上整体走偏了,看了一下别人的解答,结合deepseek的回答看了半天,终于是搞明白了里面的道道,也是醉了……
这一题我自己的思路就是一个遍历,分别考察每一个用户买与不买的情况下budget的变化以及对其下属员工price的变动,但是遇到了超时的问题。
然后deepseek给到的解答是视为一个背包问题,即不是考察每个员工买不不买的情况,而是考察给每一个员工及其下属员工分配多少的预算,然后看其最大能获得多大的利润。即,给到的最终的动态规划的数组为dp[uid][status][budget]
,其中,uid
表示用户id;status
表示其父节点的购买状态,即直属上司是否有购买行为;budget
表示给该用户及其下属所有员工分配的budget;然后dp[uid][status][budget]
整体表示当uid
用户的直属上司的购买状态为status
时,给他及其下属所有员工分配budget
预算时,能够获得的最大的profit。
由此一来,我们就可以使用动态规划进行处理了。
2. 代码实现
给出python代码实现如下:
class Solution:
def maxProfit(self, n: int, present: List[int], future: List[int], hierarchy: List[List[int]], budget: int) -> int:
tree = defaultdict(list)
for u, v in hierarchy:
tree[u - 1].append(v - 1)
@lru_cache(None)
def dp(u):
'''
input: u : int -> 0-based user id
output:
- dp0: [int] * (budget+1) -> max profit for each budget if parent node was not bought
- dp1: [int] * (budget+1) -> max profit for each budget if parent node was bought
'''
child_dp = [dp(v) for v in tree[u]]
dp0 = [0] * (budget+1) # parent not buy
dp1 = [0] * (budget+1) # parent buy
for parent_bought, max_profits in [(0, dp0), (1, dp1)]:
cost = present[u] if parent_bought == 0 else present[u] // 2
profit = future[u] - cost
dpA = [0] + [-math.inf] * (budget) # u not buy
dpB = [-math.inf] * (budget+1) # u buy
if cost <= budget:
dpB[cost] = profit
for case0, case1 in child_dp:
new_dpA = [-math.inf] * (budget+1) # u not buy
for bgt in range(budget+1):
if dpA[bgt] == -math.inf:
continue
for k in range(budget-bgt+1):
if case0[k] == -math.inf:
continue
new_dpA[bgt+k] = max(new_dpA[bgt+k], dpA[bgt] + case0[k])
dpA = new_dpA
new_dpB = [-math.inf] * (budget+1) # u buy
for bgt in range(budget+1):
if dpB[bgt] == -math.inf:
continue
for k in range(budget-bgt+1):
if case1[k] == -math.inf:
continue
new_dpB[bgt+k] = max(new_dpB[bgt+k], dpB[bgt] + case1[k])
dpB = new_dpB
for bgt in range(budget+1):
max_profits[bgt] = max(dpA[bgt], dpB[bgt])
return dp0, dp1
max_profits, _ = dp(0)
return max(max_profits)
提交代码评测得到:耗时2362ms,占用内存22.8MB。