1. 用递归的方法求兔子数列
(1)优点:程序代码简洁明了
(2)缺点:当数据规模较大时,运行时间很长,原因是有重复计算
(3)优化:用动态规划算法进行优化(记忆化搜索)
#include <bits/stdc++.h>
using namespace std;
int f(int n);
int main()
{
cout<<f(60);
return 0;
}
int f(int n)
{
if(n<=2)
{
return 1;
}
else
{
return f(n-1)+f(n-2);
}
}
2. 记忆化搜索求兔子数列
注:额外用空间换取时间
#include <bits/stdc++.h>
using namespace std;
int a[1000];
int f(int n);
int main()
{
cout<<f(60);
return 0;
}
int f(int n)
{
if(a[n]==0)//没有算过才进行计算
{
if(n<=2)
{
a[n]=1;
}
else
{
a[n]=f(n-1)+f(n-2);
}
}
return a[n];
}
3. 动态规划
(1)动态规划是一步一总结,步步为营
(2)动态规划的关键是递推公式(非常难推出,即状态转移方程)
(3)动态规划的代码很短,但是非常难理解,很抽象
(4)常用名词:阶段,阶段变量,状态,状态变量
#include <bits/stdc++.h>
using namespace std;
long long f[1000];
int main()
{
int n=60;
f[1]=f[2]=1;
for(int i=3; i<=n; i++)
{
f[i]=f[i-1]+f[i-2];//线性推导
}
cout<<f[n];
return 0;
}
动态规划的主要问题类型:
(1)背包问题:01背包(每种物品只有一个),完全背包(每种物品有无数个),多重背包(每种物品有若干个),二维背包(限制因素有2个,比如体积和重量)
注:背包问题的三要素:耗费,收益,限制
(2)最长不降子序列问题
(3)最长公共子序列问题
(4)区间动态规划问题