package
0.0.0-20241125063422-a7e1e0bf04b0
Repository: https://github.com/blueblue0102/leetcode-go.git
Documentation: pkg.go.dev

# README

740. Delete and Earn

https://leetcode.com/problems/delete-and-earn/

欲在有因果關聯的選擇中找出 maximize,所以使用 DP 的概念解題

由於 nums 中的數字是無序的,且可能有數字會重複出現
所以建立一個 points hash map,使 points[n] 即為 n * 出現次數 的值

影響決定是否選擇數字 n 的是 n-1n+1 的分數
若設計 dp(n) 為「只考慮 nums 中所有小於等於 n 的值的最大總和」
且若從 nums 中的最大值開始進行 dp() 的話
dp() 內的邏輯就變成只需要考慮 n, n-1n-2 之間的比較
若選了 n 就勢必無法選擇 n-1,但可以選擇 n-2
所以變成 points[n]+dp(n-2)dp(n-1) 之間大小的比較
(若 n 不存在於 nums 之中的話,points[n] 便是 0

// Base Cases
dp(0) = 0
dp(1) = points[1]
// General Cases
dp(2) = max(points[2]+dp(0), dp(1))
dp(3) = max(points[3]+dp(1), dp(2))
dp(4) = max(points[4]+dp(2), dp(3))
dp(n) = max(points[n]+dp(n-2), dp(n-1))

若是類似 [1, 2, 3, 10000] 這樣的 nums

上面的解法的缺點
nums = [1, 2, 3, 10000],就會將 dp(10000) dp(9999) dp(9998) ... dp(0) 逐一都計算一遍
所以一個做法是可以先將 nums 進行 sort,計算 dp 時就可以按照數字順序越過不存在的數字進行計算
只是這樣的缺點是 sort 會額外增加 $O(logn)$ 的時間複雜度
在數字很密集的 case 下會比原來的方法來的慢,得不到 sort 來越過計算不存在數字的好處

Takeaway

  • Dynamic Programming