LeetCode刷题笔记-动态规划-day3
Posted ΘLLΘ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode刷题笔记-动态规划-day3相关的知识,希望对你有一定的参考价值。
文章目录
LeetCode刷题笔记-动态规划-day3
198. 打家劫舍
1.题目
原题链接:198. 打家劫舍
2.解题思路
我们可以用f[i]
表示小偷走到第i
个房间偷的总金额,可以分两种情况:
- 小偷不选第
i
个房间的现金,那么f[i]=f[i-1];
- 小偷选择偷第
i
个房间的现金,因为不能选择连续的房间,所以f[i]=f[i-2]+nums[i];
如图:
图转载:https://www.acwing.com/solution/content/19504/
3.代码
class Solution
public:
int rob(vector<int>& nums)
int n=nums.size();
vector<int> f(n+1);
if(n<2) return nums[0];
f[0]=nums[0],f[1]=max(nums[0],nums[1]);
for(int i=2;i<n;i++)
f[i]=max(f[i-1],f[i-2]+nums[i]);
return f[n-1];
;
213. 打家劫舍 II
1.题目
原题链接:213. 打家劫舍 II
2.解题思路
从题意可知该题相比198. 打家劫舍只是多了一个条件:第一个房间和最后一个房间不能同时选,因此我们可以枚举这两种情况:
- 一定不选第一个,即求出
[2,n]
区间可以得到的最大价值 - 一定不选最后一个,即求出
[1,n-1]
区间可以得到的最大价值
最后取两种情况的最大值即可。
3.代码
class Solution
public:
int rob(vector<int>& nums)
int n=nums.size();
vector<int> f(n+1);
if(n<2) return nums[0];
if(n==2) return max(nums[0],nums[1]);
f[0]=nums[0],f[1]=max(nums[0],nums[1]);
for(int i=2;i<n-1;i++)
f[i]=max(f[i-1],f[i-2]+nums[i]);
int t1=f[n-2];
f.clear();
f[0]=0,f[1]=nums[1];
for(int i=2;i<n;i++)
f[i]=max(f[i-1],f[i-2]+nums[i]);
int t2=f[n-1];
return max(t1,t2);
;
740. 删除并获得点数
1.题目
原题链接:740. 删除并获得点数
2.解题思路
仔细分析题目可知该题与198. 打家劫舍相似,不同的是每个元素可能有多个。
因为题目要求了如果选择num[i]
,就不能选择等于 nums[i] - 1
和 nums[i] + 1
的元素,等价于198. 打家劫舍中我们不能选择连续的房间。
我们可以用map
记录每个元素的个数,由题目给出的数字范围我们可以枚举1到10000的所有元素。用f[i]
表示走到该点获取的最大点数,则:
f[i]=max(f[i-1],f[i-2]+i*cnt[i]);
3.代码
class Solution
public:
int deleteAndEarn(vector<int>& a)
map<int,int> cnt;
for(auto x:a) cnt[x]++;
vector<int> f(10001);
f[1]=1*cnt[1];
for(int i=2;i<10001;i++)
f[i]=max(f[i-1],f[i-2]+i*cnt[i]);
return f[10000];
;
以上是关于LeetCode刷题笔记-动态规划-day3的主要内容,如果未能解决你的问题,请参考以下文章