1.动态规划的思想
动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路。具体的动态规划算法多种多样,但它们具有相同的填表格式。
2.动态规划应用
在我接触的相关的算法中,求最优解、最大和、最短路径这类算法常用动态规划的思想来求解。
3.斐波那契:
定义:斐波那契数列指的是:从一个数列的第三位数开始(第1位与第2位的值均为1),每一位的值都等于前面两位的和。
那么我们如何求解斐波那契数列呢?很直观的根据数列的数值之间的关系,我会想到用递归的方式去求解。因为第一个数和第二个数默认为1,那么第三个数的值第一个数 + 第二个数,第四个数的值为 第二个数 + 第三个数,所以第n个数的值就为第 n - 1 个数 + 第 n - 2 个数。所以求第n项的和,就是求n-1项和n-2项的和。很明显是利用子问题求解的一个过程。
所以我们就可以利用递归式和递归的跳出条件来求出斐波那契数列的值了:
/*
* 斐波那契数列递归方式求解
* time:2019.6.26
* */
public int fib(int n){
//不满足斐波那契数列直接返回-1
if (n < 1){
return -1;
}
if (n == 1){
return 1;
}
if (n == 2){
return 1;
}
return fib(n - 1) + fib(n - 2);
}
迭代记忆化的求解斐波那契:
/*
* 斐波那契数列迭代的方式
* time:2019.6.26
* */
public int fib(int n){
if (n < 1){
return -1;
}
//记录第一个值
int a = 1;
//记录第二个值
int b = 1;
//记录前两个值的和
int val = 1;
for (int i = 2; i < n; i++){
val = a + b;
a = b;
b = val;
}
return val;
}