公司招到完美员工,房贷150万独生子新生儿
刚刷到个贴子,说有家公司新招了个28岁的程序员,房贷150万,独生子,刚升级当爹,老婆还没工作。老板背地里挺高兴,觉得这员工简直“天选打工人”,有责任压力,技术也过硬,肯定不会轻易跑路。
看着是真有点无语。老板这种算盘打得飞起,明里夸你优秀,心里其实盯着你的“软肋”——房贷、家庭压力,这些都是你被绑定在工位上的枷锁。
网友评论有说太现实了,也有人表示理解,说这就是职场的“性价比”逻辑,谁能为公司带来稳定价值,谁就是香饽饽。
算法题:规划兼职工作
上周六晚上,我媳妇追剧我在旁边刷手机,群里有个朋友突然发了一道算法题——说让写个“规划兼职工作”的算法,Java写。说实话一开始我脑子有点懵,这不就跟那种什么选项目赚钱一个道理嘛,后来越想越觉得这题其实还挺贴近咱们打工人的日常。
先说下场景哈,就比如你有一堆兼职机会,每个都有开始结束时间,还有个报酬,你不可能同时做两个重叠的工作,对吧?你肯定想把能赚的钱最大化。其实本质上就是一道区间动态规划的问题,我咋觉得这套路和高铁选座、会议安排、甚至约会排班都差不多...哎,题外话了,我接着说。
回到家那会儿,脑子里一团浆糊,我干脆给自己画了个时间线,每个兼职写下来,还在纸上连线,比谁“冲突”。不过后来还是回到老老实实写代码,Java嘛,咱还是习惯。其实思路就是,先把兼职按结束时间排个序,然后每次都看加上当前这个兼职赚的多,还是不加赚的多。
这东西其实递推挺明显的,你每次都要找那个不和当前兼职冲突的,离当前兼职最近的那个上一个兼职,然后加上他的最大收益。Java里写的话,二分查找用起来最舒服,这不怕和我媳妇抢遥控器,怕的就是写二分查找写抽了。
代码大致就这样,伪代码风格先来一段吧,反正你们肯定得重写一遍:
classJob{
int start, end, money;
}
publicintmaxProfit(List<Job> jobs){
// 先排序
jobs.sort(Comparator.comparingInt(a -> a.end));
int n = jobs.size();
int[] dp = newint[n];
dp[0] = jobs.get(0).money;
for (int i = 1; i < n; i++) {
// 不选当前这个
int notTake = dp[i - 1];
// 选当前这个,要找前一个不冲突的
int take = jobs.get(i).money;
int l = 0, r = i - 1;
while (l <= r) {
int m = (l + r) / 2;
if (jobs.get(m).end <= jobs.get(i).start) {
l = m + 1;
} else {
r = m - 1;
}
}
if (r >= 0) take += dp[r];
dp[i] = Math.max(notTake, take);
}
return dp[n - 1];
}
大概意思是这样,就是遍历到每个兼职时,既可以啥也不干,继续用上一份结果,也可以选这个兼职,把不冲突的最大收益加上。那关键点其实就是找前面那个不冲突的兼职,这时候二分查找的美妙你就能体会到了。以前写这玩意还傻乎乎的for一遍,现在二分一查,谁用谁舒服。
哦对,数据量大的时候别忘了排序这一步啊,之前我们组小李测试时就卡在这里,光想着动态规划结果排序没做,直接错一片,差点让他请全组奶茶。
对了对了,如果你真遇到那种兼职巨多的情况,其实也没啥特别好优化的空间,就老老实实用dp,反正时间复杂度O(nlogn),还能接受。写代码的时候,尽量把Job类单独封装,别跟我似的老用数组,后面看自己代码都懵了。
还有啊,这种题面上看起来是算法,其实全是“实用主义”思维,你们以后工作碰到需要调度安排的,别老想着做最全局最牛逼的方案,先解决80%的场景就够了。啥?再说一遍代码?得了吧,这会儿我都困了,晚点要是还有啥问题再问,先睡觉了哈。
-END-
我为大家打造了一份RPA教程,完全免费:https://www.songshuhezi.com/rpa.html