开启掘金成长之旅!这是我参与「掘金日新计划 · 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);
}