Python技术迷

父母迷信国企,花大几万把我塞进国企当流水线工人,该怎么办?

刚看到个贴子,网友吐槽父母花几万想把他塞进国企,当流水线工人。他本人在广告公司做美工,工资不高但自由点,父母却觉得进国企“稳当”,还交了定金。

Image

我觉得这事吧,是典型的代际观念冲突。父母那代人吃过社会动荡的亏,他们信“铁饭碗”,觉得稳定比啥都值钱。而年轻人更在乎成长空间和自我实现,不愿被体制束缚。两边都没错,只是看问题的角度不同。

有人说“父母是真心为你好”,也有人说“国企流水线不如外包体面”。但我觉得关键还是——谁的人生谁负责。父母出发点是爱,但工作不是他们去上,日子也不是他们来过。

换个角度看,沟通比对抗更重要。解释清楚自己的规划,也许能让父母理解。毕竟,真正的“稳当”,是你自己能养活自己、心里也不后悔。【备注:文末可领最新资料】

面试题:获得分数的方法数

你可以先脑补个小场景: 周末在家打个小游戏,每次得分只能是 2 分、3 分或者 7 分,现在你已经上头了,非要刚好打到 20 分才睡觉。问题就来了——一共有多少种不同的得分方式能刚好凑到 20 分?

这里我们先说清楚“不同”是啥意思: 只看每种分数用多少次,不看出手顺序。 比如 2+2+3 和 2+3+2,在我们眼里是同一种方式,都是「两个 2 分,一个 3 分」。

这题抽象一下就是:

  • 给定一个目标分数 target
  • 给定一个可用分数组成的列表 scores = [2, 3, 7]
  • 每种分数可以用任意次
  • 求凑出 target 的组合数(不考虑顺序)

说白了,这就是一个典型的「零钱凑法数」问题,换成得分而已。

动态规划怎么想?

你可以这么想:dp[x] 表示“凑出分数 x 的方法数”。

那我们往上凑分的时候,其实就是在问:

要凑出分数 i,如果我最后一次拿的是某个分数 s(比如 2 分), 那之前的分数就是 i - s, 而凑出 i - s 的方法数我们其实已经算过了。

所以有个特别自然的转移关系:

dp[i] += dp[i - s]

只要 i >= s,就可以把“最后拿一颗 s 分”这类方案都加进来。

关键点有两个:

  1. dp[0] = 1为啥?因为“一个分都不拿”也算一种方式,后面所有的递推都得从这个 1 开始“生长”出来。

  2. 遍历顺序要注意:

    这样保证: 对于每种分数 s,我们是“先决定用不用这种分,再累加”,不会因为顺序不同把同一种组合算很多遍。

  • 外层遍历分数种类 scores
  • 内层遍历分数 i 从 s 到 target 递增

有点绕?直接上代码你就懂了。

用 Python 写一版「组合数」解法

defcount_score_ways(target, scores):
# dp[i] 表示凑出 i 分的组合数(不考虑顺序)
    dp = [0] * (target + 1)
    dp[0] = 1# 凑出 0 分只有 1 种方式:啥也不拿

for s in scores:          # 遍历每一种得分
for i in range(s, target + 1):
            dp[i] += dp[i - s]

return dp[target]


if __name__ == "__main__":
    target = 20
    scores = [2, 3, 7]
    print(count_score_ways(target, scores))

你可以自己随便试几个:

  • target = 7, scores = [2, 3, 7]方式有:

    • 7
    • 2 + 2 + 3 一共 2 种,代码也会输出 2。
  • target = 4, scores = [1, 2, 3]方式有:

    • 1+1+1+1
    • 1+1+2
    • 2+2 一共 3 种。

时间复杂度大概就是 O(target * len(scores)),空间是 O(target),在正常题目里都挺能打的。

顺便说一句:如果“顺序也算不同”呢?

有的出题人比较折磨人,会说: “2+2+3 和 2+3+2 算两种方式,因为出手顺序不同。”

这个就变成“爬楼梯”那种感觉了,转成 DP 的时候只要换一下循环顺序就行:外层是分数 i,内层是每一种得分 s,这里我简单给你放个对比代码:

defcount_score_ways_with_order(target, scores):
# dp[i]:得分顺序也区分时,凑出 i 分的方案数
    dp = [0] * (target + 1)
    dp[0] = 1
for i in range(1, target + 1):
for s in scores:
if i >= s:
                dp[i] += dp[i - s]
return dp[target]

同样是 7 分、[2,3,7],这时候:

  • 7
  • 2+2+3
  • 2+3+2
  • 3+2+2

就会算成 4 种了。

整体套路你记住三件事就够了:

  1. 定义好 dp[i] 是什么意思(凑出 i 分的方法数)。
  2. 写出转移:dp[i] += dp[i - s]。
  3. 外层循环“分数种类”就是组合数,不看顺序; 外层循环“当前分数 i”就是排列数,看顺序。

剩下就是撸代码和改参数的事了 😄

-END-

我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html

🔥虎哥私藏精品🔥

虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领