8年没涨工资,悄悄面了一家涨薪 50%,和领导说要是能涨薪 30%就留下,结果领导说:就你?涨5%都多了。。
工作8年,工资没涨?这要是放在代码里,早就被删库跑路了吧!
有位网友吐槽,自己在公司干了8年,工资纹丝不动,心一横去面了个新工作,直接涨薪50%。但对老东家有感情,想着跟领导谈谈,涨个30%就继续干。结果领导一脸震惊:“就你?涨5%都多了。”
这不就是典型的“代码写得稳如老狗,工资却停滞不前”吗?
程序员的世界里,代码写久了会被优化,架构跑久了会升级,只有工资,可能会被“遗忘”在原地。老东家嘛,总觉得你是“老代码”,改动风险大,能用就行,没必要“重构”。可新公司呢?觉得你是“新框架”,性能强,直接上生产,给的薪资也豪爽。
所以,涨薪这事,靠的不是感情,而是“市场定价”。别指望领导良心发现,手里有个更好的offer,才是最硬核的谈判筹码。【备注:文末可领最新资料】。
算法题:粉刷房子
刷房子这事儿,我是熟的——当然,不是现实里拿着刷子去涂墙,而是算法里那种“粉刷房子”问题。
这个问题一看就像是装修预算优化,但实际上,考察的是动态规划(Dynamic Programming,简称 DP)的思维。
问题大概是这样的:有一排房子,每个房子可以涂成三种颜色之一,但相邻的房子不能是同一种颜色。每个颜色的粉刷成本不同,求最小的粉刷总成本。
说白了,就是找出一种刷墙策略,既能省钱,又不违规(相邻不同色)。要是现实中装修也能这么优化就好了,每个包工头都得来刷一遍 DP 了。😂
好,那我们来看怎么搞:
首先,定义一个 costs 数组,它是 n x 3 形态的,其中 costs[i][j] 代表粉刷第 i 号房子,使用颜色 j(0-红,1-蓝,2-绿)所需的费用。
costs = [
[17, 2, 17],
[16, 16, 5],
[14, 3, 19]
]
看到这种“最优决策 + 约束条件”,标准的动态规划问题啊!
我们定义 dp[i][j] 表示粉刷到第 i 号房子,并且选 j 颜色时的最小总费用。那么这个问题的状态转移方程就很清楚了:
dp[i][0] = min(dp[i-1][1], dp[i-1][2]) + costs[i][0]
dp[i][1] = min(dp[i-1][0], dp[i-1][2]) + costs[i][1]
dp[i][2] = min(dp[i-1][0], dp[i-1][1]) + costs[i][2]
意思是:当前房子的某种颜色 j,需要从上一个房子非 j 的两种颜色中选择最小的成本,再加上当前房子的刷漆成本。简单来说,每次选择时要避开前一个房子的颜色,并累加最小花费。
我们可以直接优化掉 dp 数组,因为 dp[i] 只依赖于 dp[i-1],所以用三个变量就能搞定,来看看代码:
def minCost(costs):
if not costs:
return 0 # 初始化前一个房子的最小花费
prev_red, prev_blue, prev_green = costs[0]
# 从第二个房子开始计算
for i in range(1, len(costs)):
curr_red = min(prev_blue, prev_green) + costs[i][0]
curr_blue = min(prev_red, prev_green) + costs[i][1]
curr_green = min(prev_red, prev_blue) + costs[i][2]
# 更新前一个房子的花费
prev_red, prev_blue, prev_green = curr_red, curr_blue, curr_green
return min(prev_red, prev_blue, prev_green)
# 试运行
costs = [
[17, 2, 17],
[16, 16, 5],
[14, 3, 19]
]
print(minCost(costs)) # 输出 10
时间复杂度: O(n) ,因为我们只遍历了一遍房子列表。
空间复杂度: O(1) ,因为只用了几个额外变量,没用额外数组。
你看,这题就像是现实生活中的租房问题:
你想租个便宜的房子(最低花费) 但又不能住在太离谱的地方(相邻颜色不同) 还得规划未来几个月的预算(动态规划)
要是现实中租房也能这么计算就好了,直接 dp 选出最优解,既能便宜又能避开奇葩室友,简直是房租优化算法 😂。
所以,刷房子这题,核心思路就是 递推+状态压缩,一步一步从最优子结构推导全局最优解。学会这个套路,啥装修预算、购房决策、人生规划,通通拿 DP 来算!(当然,人生要是能这样优化就好了……😆)
对编程、职场感兴趣的同学,大家可以联系我微信:golang404,拉你进入“程序员交流群”。