关于动态规划
基本思想:
动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。
<百度百科>
总结:
也就是说一个问题内存在重叠的子问题时,可以考虑采用动态规划,这样比较讲究,推出公式解决小问题。找出与大问题关联,求出最优解。
动态规划自下往上求解,用先前求到的子问题的解,用在解大问题上,避免重复进行计算,可以充分节省计算时间,提高运行效率。
首先给出几个例子,例如以下LeetCode的一些简单题目,如果用递归的算法,反复的从头计算,会造成过多的时间消耗。
例1: 剑指 Offer 10- II. 青蛙跳台阶问题(与70. 爬楼梯 相同)
一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
示例 1:
输入:n = 2
输出:2
示例 2:
输入:n = 7
输出:21
示例 3:
输入:n = 0
输出:1
提示:
0 <= n <= 100
来源:
力扣(LeetCode)
链接:
https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof
int numWays(int n){
int f=0,f1=1,f2=1;
if(n<2)
return 1;//一级台阶,一种跳法
//比如到了二级台阶就有了两种跳法,比如一个台阶一个台阶往上,或一次性上两个台阶爬上去
//三级台阶就有三种,前两个台阶的可能性总和f(1)+f(2)=1+2=3
//第四个台阶就有f(2)+f(3)=2+3=5个可能
//得公式:f(n)=f(n-1)+f(n-2)
for(int i=2;i<=n;i++)//自下往上,从第二个台阶开始
{
f=(f1+f2)%1000000007;//题目要求取的模
f1=f2; //存子问题计算结果
f2=f;
}
return f;
}
下面的解题原理同上,几乎一模一样
例2: 剑指 Offer 10- I. 斐波那契数列
写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下:
F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
示例 1:
输入:n = 2
输出:1
示例 2:
输入:n = 5
输出:5
提示:
0 <= n <= 100
来源:
力扣(LeetCode)
链接:
https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof
int fib(int n){
// if(n<=1)
// return n;
// return fib(n-1)+fib(n-2);
//此题在LeetCode使用递归,显示耗时过多,递归语句简单方便,但却有很多重复的运算,在进行数值大的计算时,就显得力不从心了
int f,f0=1,f1=1;
if(n<2)
{
return n;
}
else if(n==2)
{
return 1;
}
for(int i=2;i<n;i++)
{
f=(f0+f1)%1000000007;
f0=f1;
f1=f;
}
return f;
}
先氵这些,刚学,可能还会更新,看做题情况,目前先过一下基础算法