剑指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:

  • 要求什么就设什么为动态规划的数组元素含义,然后去看最后一个和前一个的联系
  • 注意数组为空的时候啊!
posted @ 2022-11-15 15:40  神鹏佐佑  阅读(23)  评论(0)    收藏  举报