题目描述
思路
-
暴力做的。注意需要对dfs加上记忆化搜索。其实,我对于这里为什么一定要加上cache进行记忆化不甚了解。能过就行。
-
DAG-DP 你也可以用DP做,那就是在DAG图上做,你需要定义这样的状态:
dp[x][k][s] = true, 表示以x节点为结束,已经选取了k条边,且这个路径的权值和为s是存在的。 当然落实到代码上,你没有必要开出第三个维度,你可以直接用一个set来代表第三个维度。
那么好了,怎么进行状态转移呢?你需要用以x为结尾的所有你记录的合法状态,去更新x的下一步节点y(假设w为x到y的权值)。
当 且 。所以你发现,这个题的状态更新其实是一种刷表的形式,即你用当前状态去更新将来的状态。当你未来枚举到将来的状态的时候,它已经完成了状态更新。
代码
- 记忆化搜索
class Solution:
def maxWeight(self, n: int, edges: List[List[int]], k: int, t: int) -> int:
g = [[] for _ in range(n)]
for a , b , w in edges :
g[a].append([b,w])
ans = -1
@cache
def dfs(node , num_edge , sum_weight) :
nonlocal ans
# invalid
if num_edge > k : return
if sum_weight >= t : return
# update ans
if num_edge == k and sum_weight < t :
ans = max(ans,sum_weight)
return
# dfs
for b , w in g[node] :
dfs(b, num_edge + 1 , sum_weight + w)
for a in range(n):
dfs(a,0,0)
return ans
- DAG-DP
class Solution:
def maxWeight(self, n: int, edges: List[List[int]], k: int, t: int) -> int:
g = [[] for _ in range(n)]
d = [0] * n
for a , b , w in edges :
g[a].append([b,w])
d[b] += 1
f = [[set() for _ in range(k+1) ] for _ in range(n)]
q = [ i for i,x in enumerate(d) if x == 0 ]
ans = -1
while q :
node = q.pop(0)
f[node][0].add(0)
if len(f[node][k]) :
ans = max(ans,max(f[node][k]))
for b , w in g[node]:
for i in range(k):
for s in f[node][i] :
if s + w < t :
f[b][i+1].add(s + w)
d[b] -= 1
if d[b] == 0 :
q.append(b)
return ans