动态规划算法详解基础篇

目录

动态规划解决什么样的问题?

如何理解动态规划?

如何学好动态规划?

动态规划和递归的一些关系

动态规划三部曲


动态规划解决什么样的问题?

1、求最值问题:最大值、最小值。

2、字符串问题:如果是两个字符串的则95%用动态规划,剩下的5%比较简单。

3、一般可以用暴力法做。

如何理解动态规划?

1、动态规划一般是最优解,并且关注的是时间上的最优解。

2、通过利用历史记录来找出一些规律,进而更好的去规划一些东西,最后可以避免一些重复计算。

如何学好动态规划?

一般很多人都处于给了答案看得懂,但自己不会做,无从下手。我们要多刷题,通过套路刷,不理解为啥这样套没关系,先会用套路来做。

动态规划和递归的一些关系

例题:

斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:

f(0) = 0,f(1) = 1
f(n) = f(n - 1) + f(n - 2),其中 n > 1

给定 n ,请计算 f(n) 。

示例 1:

输入:n = 2
输出:1
解释:f(2) = f(1) + f(0) = 1 + 0 = 1
//递归做法,有大量重复计算,复杂度是2^n
int f(int n){
  if(n <= 2){
   return 1; 
 }

int sum = f(n - 1) + f(n - 2);

   return sum;

 }
// 优化版本(状态保存) 复杂度是n
//从上往下算
int []arr = new arr[n + 1];//初始值都是0
int f(int n){
  if(n <= 2){
   return 1; 
 }
if(arr[n] != 0){
   return arr[n];
  }

int sum = f(n - 1) + f(n - 2);
   arr[n] = sum;

   return sum;

 }
//动态规划版本
//我们可以从下往上
int f(int n){
//1.定义我们dp数组的含义:求什么就定义成什么
//dp[i]表示第i项的值
  int dp[] = new int[n + 1];
  dp[1] = 1;
  dp[2] = 1;

//2.找出dp数组间的关系式:dp[i]  = dp[i - 1] + dp[i - 2]

//3.找出初始值:i从3开始 dp[1] dp[2]就需要我们手动赋初始值
  
  for(int i = 3; i <= n; i++){
    dp[i] = dp[i - 1] + dp[i - 2];  

}


   return dp[n]

}

用递归 -----> 优化成状态保存避免重复计算---->看一下能否变成自底向上。

动态规划三部曲

1、定义我们dp数组的含义。

2、找出dp数组之间关系式。

3、找出初始值。

现在我们可以再返回去看斐波那契数列的动态规划版本的代码的注释,加深一下理解。接下来我会写关于动态规划基础篇的例题练习一下,以后会出进阶篇讲解及例题。

你可能感兴趣的:(#数据结构与算法,算法,动态规划,数据结构,java,开发语言)