(线性dp)LeetCode740. 删除并获得点数
(线性dp)LeetCode740. 删除并获得点数
思路
同打家劫舍,第\(i\)个到底选不选
可以开一个二维数组记录状态
值得注意的是可以先排序再去重,同时用哈希表记录次数(具体可以看代码),因为假如选了\(n\)这个数,所有的\(n\)肯定都要选,这样才保证结果最大
代码
vector<int> my;
unordered_map<int, int> mp;
int deleteAndEarn(vector<int>& nums)
{
int cnt = 0;
sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size(); i++)
{
if (!mp[nums[i]])
{
my.push_back(nums[i]);
cnt++;
}
mp[nums[i]]++;
}
int dp[20010][2] = {0};
// dp[i][1/0]:前i个元素第i个元素选/不选能够获得的最大值
// 如果选的话:if (my[i - 1] == my[i] - 1) dp[i][1] = dp[i - 1][0] + nums[i], else dp[i][1] = max(dp[i - 1][0], dp[i - 1][1]) + my[i] * mp[my[i]]
// 如果不选的话:dp[i][0] = max(dp[i - 1][1], dp[i - 1][0])
dp[0][1] = my[0] * mp[my[0]];
for (int i = 1; i < cnt; i++)
{
if (my[i - 1] == my[i] - 1)
{
dp[i][1] = dp[i - 1][0] + my[i] * mp[my[i]];
}
else
{
dp[i][1] = max(dp[i - 1][0], dp[i - 1][1]) + my[i] * mp[my[i]];
}
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1]);
}
return max(dp[cnt - 1][0], dp[cnt - 1][1]);
}

浙公网安备 33010602011771号