Press "Enter" to skip to content

Huahua's Tech Road

花花酱 LeetCode 646. Maximum Length of Pair Chain

这题我选DP,因为不需要证明,直接干就行了。

方法1: DP

首先还是需要对pairs的right进行排序。一方面是为了方便chaining,另一方面是可以去重。

然后定义 dp[i] := 以pairs[i]作为结尾,最长的序列的长度。

状态转移:dp[i] = max(dp[j] + 1) where pairs[i].left > pairs[j].right and 0 < j < i.

解释:对于pairs[i],找一个最优的pairs[j],满足pairs[i].left > pairs[j].right,这样我就可以把pairs[i]追加到以pairs[j]结尾的最长序列后面了,长度+1。

边检条件:dp[0:n] = 1,每个pair以自己作为序列的最后元素,长度为1。

时间复杂度:O(n2)
空间复杂度:O(n)

方法2: 贪心

和DP一样,对数据进行排序。

每当我看到 cur.left > prev.right,那么就直接把cur接在prev后面。我们需要证明这么做是最优的,而不是跳过它选后面的元素。

Case 0: cur已经是最后一个元素了,跳过就不是最优解了。

假设cur后面有next, 因为已经排序过了,我们可以得知 next.right >= cur.right。

Case 1: next.right == cur.right。这时候选cur和选next对后面的决策来说是一样的,但由于Case 0的存在,我必须选cur。

Case 2: next.right > cur.right。不管left的情况怎么样,由于right更小,这时候选择cur一定是优于next。

综上所述,看到有元素可以连接起来就贪心的选它就对了。

时间复杂度:O(nlogn)
空间复杂度:O(1)

花花酱 LeetCode 514. Freedom Trail

一眼DP,看数据规模标程应该是O(1003)。

阶段肯定就是吟唱完一个字符,状态和哪个字符在12:00点有关。

所以我们定义 dp[i][j] := 吟唱完keys[0~i]后,rings[j]停在12:00点所需要的最少步数。

转移方程:dp[i][j] = min(dp[i-1][k] + steps(k, j) + 1) if keys[i] == rings[j] else +inf.

第i-1字符吟唱完ring停留在k,第i个字符吟唱完ring停留在j (rings[j] 必须和 keys[i] 相同),steps(k, j)表示ring从k转到j所需要的最少步数,最后还要+1,表示吟唱当前字符所需要的额外步骤。

边界条件:对于第0个字符,ring一开始停留在第0个字符,最小步数就是1 + steps(0, key[0])。

时间复杂度:O(mn2)
空间复杂度:O(mn) 可以降维到 O(n)

花花酱 LeetCode 462. Minimum Moves to Equal Array Elements II

不太喜欢这样的题目,你需要证明/猜测最优解是将所有数字转换成median/中位数。

使用nth_element找中位数,然后再循环一遍求合即可。

时间复杂度:O(n)
空间复杂度:O(1)

聊聊Switch2 | 价格 | Key Card | 二手

Switch2终于发布了,游戏画面看着还不错,有点”次世代”的感觉了呢~

Switch 2真的贵吗?

几乎所有人都在吐槽价格。正所谓没有不好的产品,只有不好的定价。美版首发定价$449.99,如果对比Switch 2017年首发时$299.99定价,贵了足足有50%。但在美国的同学应该都能感受到这几年的通胀,很多商品的价格都涨了不止50%。考虑到Switch2的物料成本(去除通胀)肯定是要比Switch要高不少的,所以说这个价格看着有些抽象,但其实确实在合理范围里面。有人说这个价格都赶上PS5了,但老任可不会干亏本卖机器,靠游戏回血的勾当,而是我都要~ 个人觉得如果定在$399的话,大部分人应该都能接受了吧。


microSD Express

看了一眼价格256G $60,其实还可以。我两个月前买的128G UHS-I V30的卡也要30刀呢(现在怎么降到16刀了~)。机内的230G,买一张256G的卡,放个几十个数字版/Key Card的游戏应该问题不大,能满足绝大多数人的需求了。再说了,你买得起几十个游戏吗,就来吐槽存储卡贵?关于microSD Express only,其实没啥好说的,目前价格应还算合理,以后只会越来越便宜,换来更快的加载速度完全是值得的。

目前爆料的一些游戏容量:

  • Mario Kart World: 23.4 GB
  • Donkey Kong Bananza: 10 GB
  • Nintendo Classics: GameCube app: 3.5 GB
  • Super Mario Party Jamboree – Nintendo Switch 2 Edition + Jamboree TV: 7.7 GB
  • Kirby and the Forgotten Land – Nintendo Switch 2 Edition + Star Crossed World: 5.7 GB

Cyberpunk 2077 会使用64GB的卡带,而非Key-Card。每个实体版的游戏相当于一张小的SD存储卡了。

卡带 / Key Card

时至今日只有老任还在坚持使用卡带,对比与蓝光光碟,那种即插即玩的体验懂的都懂。代价是什么?高昂的制造成本。但是,这一切会被Key Card所终结吗?其实在Switch 1时代就有半Key Card的游戏,部分游戏放在8GB的卡带中(16/32GB的卡带在当时太贵了),剩下的部分需要下载。用这种方式降低发行成本,其实也是无可厚非的选择。由于Switch 2的机能提高了不少,贴图精度必然水涨船高,结果就是游戏容量暴增。虽然还不能和PC和PS5比,但已经达到卡带的极限了,Key Card的推出只能说被时代推着走。这么说来Swtich 1机能弱/游戏小还是某种优势咯(笑)。其实在Switch 1时代,我就想要比完整游戏版卡带便宜一些Key Card了/或者直接说是带包装盒的数字版下载码。对比卡带,游戏的包装盒对我而言的收藏的意义更大一些。这算是现代版的买椟还珠吗?

我的PS5实体游戏到现在还没拆封…

游戏价格 |二手 | 氪金 |盗版

网友们接着吐槽游戏价格贵。实体版比数字版价格贵我觉得是合理的,毕竟多一个包装盒呢,游戏卡带算是附加送的(笑)。主要的是卡带/Key Card可以出二手。回血玩家们转手十来次,老任只收了一份的钱,不得哭晕在厕所啊。这时Intel/AMD/Nvida/Apple同时站出来说,没有人比我更懂转手几十次的垃圾佬。关于二手商品的流通对厂商的影响、以后会单独写一篇文章。

为什么大家会觉得现在的游戏贵?说贵的同学可以看看九十年代FC游戏的定价。就拿我最喜欢的《火焰之纹章-外传》来说,1992年在日本的发行价格为6800日元,就算不考虑通胀,当时的价格为现在汇率下的47刀,或者336人民币。92年,336人民币什么概念?可能要1个多月工资了。当时国内的FC卡带几乎都是盗版的,但毕竟成本摆在那里,在上海普遍的价格是100多人民币一盒,记得容量更大的《吞食天地 – 诸葛孔明传》更是要价250元。当时买游戏卡绝对是一件奢侈的事情,过年的时候拿着压岁钱咬牙买了一盒《松鼠大战2》,记得好像是125元,那是95年前后吧。有时侯也会和街坊邻居/同学交换游戏卡玩,也算是某种形式的回血了。

九十年代后期,那时候兴起了多媒体电脑热,1万元左右的价格咬咬牙还是买得起的,家里有台电脑还倍有面子,所以游戏也渐渐转移到PC上面(毕竟当时个人拥有SFC/PS/SS的是少数)。游戏的载体也变成CD,当然绝大多数都是盗版的,起初价格还要15元,后来10元,最后慢慢稳定到5元一张碟。游戏玩家快速成长,再也没有人觉得游戏贵了。

再后来到了2002年前后,宽带开始普及,游戏也从购买CD变成了网上下载,当然还是盗版的,但获取单机游戏的边际成本趋近于0。

当时很多网游都是要充点卡的,还是有些小贵。当然比起拨号+点卡时代已经便宜很多了。我玩《石器时代》拨号费可能都花了几千块钱…

再后来氪金网游/手游开始大行其道,从此开启了正版游戏也能免费玩的时代。

但不管在什么年代,正版的单机大作卖的一直不便宜,只是提及的人比较少,或者说其受众多说能够接受这个定价,吐糟的大多都是伸手党。

说了这么多,不是想给老任/Sony开脱,虽然开发工具/生产力大幅提升了,但现代游戏开发成本和当年比起来是高了一个数量级都不止,要不是游戏玩家变多了平摊掉不少成本,不然游戏价格还会更贵。

虽然游戏的定价对于发展中国家来说还是比较贵的,不锁区没办法,但对于美国玩家来说,大作$80刀,1天的工资都不到,你觉得这个价格还贵吗?

对于一些人来说,缺少的哪里是那80刀,而是玩游戏的时间和热情。

Switch 2 我还是会买的(但可能要等到减肥成功之后)手持1080p 60绝对是足够了。

我更愿意以合理的价格玩到优秀的游戏,而不愿用便宜的价格玩粗制滥造的玩意儿。

感觉这次Switch 2可能会撑10年,希望是我预测错了~

以上,

花花

花花酱 LeetCode 403. Frog Jump

肯定是用DP,但我自己想了一个奇怪的方法,勉强过了…

使用dp[i] = {steps},表示可以达到stones[i]的最后一跳的unit的集合。
dp[0] = {0}
dp[1] = {1} if stones[1] = 1 else {}
然后对于stones[i],枚举所有step – 1, step, step + 1三种情况,看看是否可以跳到新的石头上面(使用一个hashtable判断),如果可以的吧,把跳的unit存到dp[j]中。相当于推了。
需要使用hashset去重,不然会超时。

时间复杂度:O(n2)
空间复杂度:O(n2)

“优化”:由于每次只能k-1,k,k+1steps,所以最大的units和n是线性关系,达到stones[i]最多跳i+1个units。
可以用二维数组dp[j][k] := 是否可以通过k步跳到stones[j].
dp[j][k] = dp[i][k-1] || dp[i][k] || dp[i][k+1], k = stones[j] – stones[i]. 即从stones[i]跳到stones[j],并且要求跳到stones[i]的可能步数中存在k-1,k,k+1。
时间复杂度和空间复杂度是一样的。