第N个斐波那契数列
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
public:
int tribonacci(int n) {
int a[4]={0,1,1,2};
if(n<4) return a[n];
int k=n-3;
for(int i=0; i<k;i++)
{
int tmp=a[3];
a[3]=a[1]+a[2]+a[3];//不是【0】开始,而是【1】开始
a[0]=a[1];
a[1]=a[2];
a[2]=tmp;
}
return a[3];
}
};
三步问题
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
public:
int waysToStep(int n) {
vector<int> dp(n+1,1);
if(n==1) return 1;
dp[1]=1;
dp[2]=2;
for(int i=3; i<n+1; i++)
{
dp[i]= ((dp[i-1]+dp[i-2])%1000000007+dp[i-3])%1000000007;//数据超出整形题目的要求处理
}
return dp[n];
}
};
最小花费爬楼梯
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
int n=cost.size();
vector<int> dp(n,0);
dp[0]=cost[0],dp[1]=cost[1];
for(int i=2; i<n; i++)
{
dp[i]=min(dp[i-1],dp[i-2])+cost[i];
}
return min(dp[n-1],dp[n-2]);
}
};
解码的方法
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
public:
int numDecodings(string s) {
int n=s.size();
//if(n==1) return 1;不一定能解码成功
vector<int> dp(n+1);
//dp[0]=1,dp[1]=1;//s[0]不一定能解码成功
dp[0]=1;
for(int i=1; i<n+1; i++)
{
//if(s[i-2]!=0&&((s[i-2]*10+s[i-1])<='Z'))//填表的映射,画图理解。
if(s[i-1]!='0')//单独解码,注意填的是字符‘0’
dp[i]+=dp[i-1];
if(i>1&&s[i-2]!='0')
{
int a=s[i-2]-'0',b=s[i-1]-'0';
if(a*10+b<=26)
dp[i]+=dp[i-2];
}
}
for(auto e:dp)
{
cout<<e<<endl;
}
return dp[n];
}
};
打家劫舍
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
public:
int rob(vector<int>& nums) {
int n=nums.size();
vector<int> f(n+1);//偷的dp表
vector<int> g(n+1);//不偷的dp表,f[0],g[0]都是初始化为0
for(int i=1; i<n+1; i++)
{
f[i]=g[i-1]+nums[i-1];
g[i]=max(g[i-1],f[i-1]);
}
return max(f[n],g[n]);
}
};
打家劫舍||
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
public:
int n=0;
int rob(vector<int>& nums) {
//偷了第一个就不能偷最后一个,偷的区间变成了[0,n-2]
//偷了最后一个就不能偷第一个,..............[1,n-1]
n=nums.size();
if(n==1) return nums[0];
return max(r(nums,0,n-2),r(nums,1,n-1));
}
int r(vector<int>& nums, int left, int right)
{
vector<int> f(n);//偷的dp表
vector<int> g(n);//不偷的dp表,f[0],g[0]都是初始化为0
for(int i=1; i<n; i++)
{
f[i]=g[i-1]+nums[left];
left++;
g[i]=max(f[i-1],g[i-1]);
}
return max(f[n-1],g[n-1]);
}
};
利用左右区间固定的方法,封装性更好
class Solution {
public:
int n=0;
int rob(vector<int>& nums) {
//偷了第一个就不能偷最后一个,偷的区间变成了[0,n-2]
//偷了最后一个就不能偷第一个,..............[1,n-1]
n=nums.size();
if(n==1) return nums[0];
return max(r(nums,0,n-2),r(nums,1,n-1));
}
int r(vector<int>& nums, int left, int right)
{
vector<int> f(n+1);//偷的dp表
vector<int> g(n+1);//不偷的dp表,f[0],g[0]都是初始化为0
// for(int i=1; i<n; i++)
// {
// f[i]=g[i-1]+nums[left];
// left++;
// g[i]=max(f[i-1],g[i-1]);
// }
for(int i=left+1; i<=right+1; i++)
{
f[i]=g[i-1]+nums[i-1];
g[i]=max(f[i-1],g[i-1]);
}
return max(f[right+1],g[right+1]);
//return max(max(f[n-1],g[n-1]),max(f[n],g[n]));
}
};
删除并获得点数
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
public:
int deleteAndEarn(vector<int>& nums) {
//把所有相同的数字映射在对应下标下,并计算他们的和,意思就是删除这个数所获得的这个数的所有存在之和
//把零也作为打家劫舍要处理的部分,因为不值得额外处理
//同样必须把预处理后的数组全部读完
int n=nums.size();
int a[20001]={0};
for(auto e:nums)
{
a[e]+=e;
}
vector<int> f(20002);
vector<int> g(20002);
for(int i=1; i<20002; i++)
{
f[i]=g[i-1]+a[i-1];
g[i]=max(f[i-1],g[i-1]);
}
return max(f[20001],g[20001]);
}
};
优化方法:可以先遍历一遍数组找到最大值,只建立刚好映射最大数字的数组,在数据范围小的时候,这样可以大大减少后续遍历的时间。
class Solution {
public:
int deleteAndEarn(vector<int>& nums) {
//把所有相同的数字映射在对应下标下,并计算他们的和,意思就是删除这个数所获得的这个数的所有存在之和
//把零也作为打家劫舍要处理的部分,因为不值得额外处理
//同样必须把预处理后的数组全部读完
int n=nums.size();
//int a[20001]={0};
int nums_max=0;
for(auto e:nums)
{
nums_max=max(e,nums_max);
}
vector<int> a(nums_max+1);//刚好能够映射max的下标
for(auto e:nums)
{
a[e]+=e;
}
vector<int> f(nums_max+2);
vector<int> g(nums_max+2);
for(int i=1; i<nums_max+2; i++)
{
f[i]=g[i-1]+a[i-1];
g[i]=max(f[i-1],g[i-1]);
}
return max(f[nums_max+1],g[nums_max+1]);
}
};
粉刷房子
class Solution {
public:
int minCost(vector<vector<int>>& costs) {
int n=costs.size();
vector<vector<int>> dp(n+1,vector<int>(3));
for(int i=1; i<n+1; i++)
{
//1.这里是用costs的0位置来填dp表的1号位置
//2.这层三种选择,每种选择都会影响前一种选择
dp[i][0]=min(dp[i-1][1],dp[i-1][2])+costs[i-1][0];
dp[i][1]=min(dp[i-1][0],dp[i-1][2])+costs[i-1][1];
dp[i][2]=min(dp[i-1][0],dp[i-1][1])+costs[i-1][2];
}
return min(min(dp[n][0],dp[n][1]),dp[n][2]);//需要用两个min,而不是三个
}
};