ให้อาร์เรย์ nums ทำการดำเนินการซ้ำ: เลือก nums[i] ลบออก ได้คะแนน nums[i] แต่ต้องลบ ทุกตัว ที่มีค่า nums[i]-1 และ nums[i]+1 ด้วย หาคะแนนสูงสุดที่ได้
ตัวอย่าง: [3,4,2] → 6 (ลบ 4 ได้ 4 คะแนน 3 ถูกลบอัตโนมัติ แล้วลบ 2 ได้ 2 คะแนน รวม 6)
ขั้นตอนการแก้ปัญหา (DP บนค่าที่ไม่ซ้ำ)
- นับความถี่แต่ละค่าใน
map m - เรียงค่าที่ไม่ซ้ำ (key ของ map) 從小到大
- DP แบบ House Robber: สำหรับค่า
xเรียงลำดับ:- คะแนนถ้าเลือก
x=x * freq[x] - ถ้าค่าก่อนหน้า
prevติดกัน (x - prev == 1) → ไม่สามารถเลือกทั้งคู่ได้:dp[x] = max(dp[prev], x*freq[x] + dp[prev2]) - ถ้าไม่ติดกัน → เลือกได้พร้อมกัน:
dp[x] = dp[prev] + x*freq[x]
- คะแนนถ้าเลือก
- คืนค่าสูงสุด
ตัวอย่างโค้ด C++
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
int deleteAndEarn(vector<int>& nums) {
map<int, int> freq;
for (int x : nums) freq[x]++;
int prev = -1, prev2 = -1;
int take = 0, skip = 0;
for (auto& [x, cnt] : freq) {
int curTake = x * cnt;
if (prev != -1 && x == prev + 1) {
int newTake = skip + curTake;
int newSkip = max(take, skip);
take = newTake; skip = newSkip;
} else {
int best = max(take, skip);
take = best + curTake;
skip = best;
}
prev2 = prev; prev = x;
}
return max(take, skip);
}
};
int main() {
vector<int> v = {3,4,2};
Solution ob;
cout << ob.deleteAndEarn(v);
}
Input
[3,4,2]
Output
6