本文已参与「新人创作礼」活动,一起开启掘金创作之路。
2022-02-10 每日打卡:难题精刷
写在前面
“这些事儿在熟练之后,也许就像喝口水一样平淡,但却能给初学者带来巨大的快乐,我一直觉得,能否始终保持如初学者般的热情、专注,决定了在做某件事时能走多远,能做多好。” 该系列文章由python编写,所刷题目共三个来源:之前没做出来的 ;Leetcode中等,困难难度题目; 周赛题目;某个专题的经典题目,所有代码已AC。每日1-3道,随缘剖析,希望风雨无阻,作为勉励自己坚持刷题的记录。
选课
刚开始以为是类似最小生成树,使用了贪心+栈的方法。后来发现因为【存在步数限制】,所以不能保证所有的结点都被检查到。也就说明,可能后来更大的分数因为没有走到而被忽略。
所以一个比较显著的思路是dfs,然而最终【选择最优路径】是通过dp来的,原因在于可以选择【当前结点的兄弟结点】或者【沿着当前结点一直走下去】,dp的过程也就是dfs的返回过程,直接写到一起即可。
import collections
m,n = [int(i) for i in input().split(" ")]
pre = collections.defaultdict(list)
ans = [[0 for i in range(n+2)]
for i in range(m+2)]
for line in range(1,m+1):
p, q = [int(i) for i in input().split(" ")]
pre[p].append(line)
# 从当前开始选择一个结点
ans[line][1] = q
def dfs(idx):
for nxt in pre[idx]:
# 先计算叶结点再计算根结点
dfs(nxt)
# 对每个idx而言,可能把step步放到这个结点
for step in range(n+1, 0,-1):
# 对这step步而言,可以是向下走,也可以向叶子走
for leaves in range(0,step,1):
ans[idx][step] = max(ans[idx][step], ans[idx][step-leaves]+ans[nxt][leaves])
dfs(0)
print(ans[0][n+1])