剑指offer——Day08动态规划(简单)
Day8 2022.11.14 动态规划(简单)
10.Ⅰ.斐波那契数列
自己实现
两个两个往后面加即可,注意要%
代码如下:
class Solution {
public:
int fib(int n) {
vector<int> vec;
if(n==0)return 0;
vec.push_back(0);
vec.push_back(1);
int i=2;
while(i<=n)
{
vec.push_back((vec[i-2]+vec[i-1])%1000000007);
i++;
}
return vec[--i]%1000000007;
}
};
代码表现

hint:
- 不要把对象名写成容器种类了!
10.Ⅱ.青蛙跳台阶问题
自己实现
其实就是斐波那契数列,因为最后一步有两种情况:
- n-1个台阶有f(n-1)种跳法,最后还剩一个台阶,最后青蛙只能跳一级
- n-2个台阶有f(n-2)种跳法,最后青蛙一次跳两级(两次跳一级的情况已经在f(n-1)中被包含了)
所以f(n)=f(n-1)+f(n-2)
代码如下:
class Solution {
public:
int numWays(int n) {
vector<int> vec;
if(n==0)return 1;
vec.push_back(1);
vec.push_back(1);
int i=2;
while(i<=n)
{
vec.push_back((vec[i-2]+vec[i-1])%1000000007);
i++;
}
return vec[--i]%1000000007;
}
};
代码表现

hint:
- 要理解这个题目需要返回的就是跳n级的跳法种类数,即f(n)的值,那就采用动态规划的思想去考虑f(n)和f(n-1), f(n-2)之间有什么联系
63.股票的最大利润
自己实现
直接用两个for来循环找最大利润,但是时间肯定很多
代码如下:
class Solution {
public:
int maxProfit(vector<int>& prices) {
int len=prices.size();
int i,j;
int max=0;
int money=0;
for(i=0;i<len-1;i++)
{
for(j=i+1;j<len;j++)
{
if(prices[i]<prices[j])
{
money=prices[j]-prices[i];
if(money>max)max=money;
}
}
}
return max;
}
};
代码表现
这时间太慢了

题解
用动态规划。设前i日中的最大利润为dp[i](要求什么就设什么为数组元素含义),那么动态规划的公式为:
前i日最大利润=max(前(i−1)日最大利润,第i日价格−前i日最低价格)
即 dp[i]=max(dp[i−1],prices[i]−min(prices[0:i]))
初始状态dp[0]=0,首日利润为0;返回值为dp[n-1],即数组的最后一个元素
代码如下:
class Solution {
public:
int maxProfit(vector<int>& prices) {
if(prices.size()==0)return 0;
int min=prices[0];
vector<int> vec;
vec.push_back(0);
for(int i=1;i<prices.size();i++)
{
if(prices[i]<min)min=prices[i];
vec.push_back(vec[i-1]>(prices[i]-min)?vec[i-1]:(prices[i]-min));
}
return vec[vec.size()-1];
}
};
代码表现

hint:
- 要求什么就设什么为动态规划的数组元素含义,然后去看最后一个和前一个的联系
- 注意数组为空的时候啊!
浙公网安备 33010602011771号