蓝桥杯备考:从记忆化搜索到动态规划
首先我们先来复习一下我们之前学的用记忆化搜索优化的求斐波那契数列
#include <iostream>
#include <cstring>
using namespace std;
const int N = 35;
int f[N];
int dfs(int n)
{
if(f[n]!=-1) return f[n];
if(n==1||n==0) return f[n]=n;
return f[n] = dfs(n-1)+dfs(n-2);
}
int main()
{
memset(f,-1,sizeof(f));
int n;cin >> n;
cout << dfs(n) << endl;
return 0;
}
动态规划就是把复杂的问题分解为更小的问题,并存储子问题的解,减少计算。动态规划除了有记忆化搜索,还有递推形式的动态规划 我们先来写一下
#include <iostream>
using namespace std;
const int N = 35;
int f[N];
int main()
{
int n;cin >> n;
f[0] = 0,f[1] = 1;
for(int i =2;i<=n;i++)
{
f[i] = f[i-1]+f[i-2];
}
cout << f[n] << endl;
return 0;
}
在递推形式的动态规划里,我们需要理解一下递归形式的动态规划的一些专有名词
1.状态表示,也就是f数组里每一个格子的含义
2.状态转移方程:也就是f数组里每一个格子的推导公式
3.初始化:根据题目的条件先填一些格子
其实递推形式第动态规划的这些名词和记忆化搜索里是能一一对上的
状态表示《-----》递归的含义 都是求第n个斐波那契数
状态转移方程《--------》递归函数的主函数体
初始化 《-------》递归函数的出口
递推形式动态规划步骤
1.确认状态表示 根据经验和递归函数的含义来定,实在不会可以尝试取蒙去试
2.推导状态转移方程
3.初始化
4.确认填表顺序
5.确定最终结果