# 对于动态规划算法的基础学习(1)

93 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

动态规划-斐波那契数列

包括基础类题目:斐波那契数列,爬楼梯;背包问题;打家劫舍;股票问题; 子序列问题

解决动态规划的需明确:

1.  明确dp数组的定义以及下标的含义,如dp[i],i的含义,dp[i]的含义;

2.  递推公式;

3.  dp数组如何初始化,有时需要初始化0,有时需要初始化1,需要明确,不是任何情况下都初始化为0;

4.  遍历顺序,如0-1背包问题时,两层for循环,需要先遍历背包后遍历物品,有的题是从前往后,有的题是从后往前,需要自己根据题目具体思考决定

简单题目学习:斐波那契数

斐波那契数列为:1 1 2 3 5 8……

可以看出其规律为,前两个数的和为第三个数的值

按照上述思路逐步解题:

1.  确定dp[i]含义,本题dp[i]的含义:第i个斐波那契数为dp[i],如第1个斐波那契数dp[1]=1,第2个,dp[2]=1,第3个dp[3]=2;

2.  递推公式,dp[i]=dp[i-1]+dp[i-2];

3.  初始化,题目已经已知,dp[0]=1,dp[1]=1;

4.  遍历顺序,第i个数的值由i-1和i-2的值确定,所以是从前向后遍历

5.  可以打印dp数组,验证结果不正确时,为何出错

代码:

class Solution {

public:

    int fib(int N) {

        if (N <= 1) return N;

        vector<int> dp(N + 1);

        dp[0] = 0;

        dp[1] = 1;

        for (int i = 2; i <= N; i++) {

            dp[i] = dp[i - 1] + dp[i - 2];

        }

        return dp[N];

    }

};

由于初系统学习,就多唠几句:

什么是vector?

vector是一个封装了动态大小数组的顺序容器。和任意其他类型容器一样,它能够存放各种类型的对象,可以简单的认为,向量是一个能够存放任意类型的动态数组。

容器特性:

顺序序列:顺序容器中的元素按照严格的线性顺序排序,可以通过元素在序列中的位置访问对应的元素;

动态数组:支持对序列中的任意元素进行快速访问,如指针等,相较于我们普通的定义数组其比较方便。

基本实战应用:

#include <string.h>

#include <vector>

#include <iostream>

#include<algorithm>//对于sort排序需要适用头文件

using namespace std;

int main()

{
    vector<int>obj;//创建一个向量存储容器 int

    for(int i=0;i<10;i++) // push_back(elem)在数组最后添加数据

    {
        obj.push_back(i);

        cout<<obj[i]<<",";   
    }
    for(int i=0;i<10;i++)//去掉数组最后一个数据

    {

        obj.pop_back();

    }
    for(int i=0;i<obj.size();i++)//size()容器中实际数据个数

    {  cout<<obj[i]<<",";

    }

    obj.clear();//清除容器中所有数据

    sort(obj.begin(),obj.end());//从小到大

    reverse(obj.begin(),obj.end());//从大到小
    return 0;

}

如果想要运行上述程序:

可以加头文件:

#include<string>

#include<vector>

#include<iostream>

using namespace std;

以及main函数:

int main()

{

    Solution a;

    a.fib(2);

}