Title

(线性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]);
}
posted @ 2024-10-02 21:26  栗悟饭与龟功気波  阅读(25)  评论(0)    收藏  举报