基本内容:

这几天学习了一下动态规划,特此整理。

在一道题中反复使用或者反复计算,将重复的内容存到一个集合里面,计算后面的时候直接从集合里面取值,可以大幅优化时间和空间。

核心:记住求过的解来节省时间。

 

例:

计算:1+1+1+1+1

结果 不使用动态规划加五次得到 5

 

计算:给上面式子加一

结果:使用动态规划:计算过程为取上面结果,给结果加1,只进行一次计算。(很快就能计算出来)

 

动态规划有两种形式:

1.自顶向下的备忘录法(空间复杂度高)

2.自底向上(推荐)

 

为了说明两种方法:举一个简单例子:

斐波那契数列:1 1 2 3 5 8 13 ...........

Fibonacci(n)  =  1;  n  =  0;

Fibonacci(n)  =  1;  n  =  1;

Fibonacci(n)  =  1;  n  = Fibonacci(n-1)  +  Fibonacci(n-2) ;

 

自顶向下(递归):

 1 public class DP{
 2     public static int f(int n){
 3         if(n==0){
 4             return 1;
 5         }
 6          if(n==1){
 7             return 1;
 8          }
 9         return f(n-1)+f(n-2);
10     }
11     public static void main(String args[]){
12            int n=5;
13             f(n);
14     }
15 }

这个复杂度是一个树形结构,十分复杂,O(2^n)

如果将f(0),f(1),f(2).......存入表中,如果计算时,算过就从表中直接取.

 

自顶向下(递归)动态规划(备忘录法)(因为使用了递归,所以空间复杂度较高)

简单来说就是使用一个数组或者集合或者其他,将已经计算过的值存在里面,计算的时候,先查看这个位置的值有没有被计算过,有就返回,没有就计算。

这里的数组就相当于一个备忘录

 1 public class DP{
 2     public static void main(String args[]){
 3                 int n=5;
 4                 int[] bak=new int[n+1];
 5                 for(int i=0;i<n+1;i++){
 6                     bak[i]=-1;
 7                 }
 8                 System.out. println(f(n,bak));
 9             }
10     public static int f(int n,int[] bak){
11         if(n==0){
12             return 1;
13         }
14         if(n==1){
15             return 1;
16         }
17         if(bak[n] !=-1){
18             return bak[n];
19         }
20         int result =f(n-1,bak)+f(n-2,bak);
21         bak[n]=result;
22         return result;
23     }
24 
25 }

 

 自底向上:

就是说不使用数组,使用两个值r1,r2,代表r1,r2,从最开始向目标计算

 1 public class Main{
 2     public static void main(String args[]){
 3         int n=5;
 4         System.out. println(f(n));
 5     }
 6     public static int f(int n){
 7         if(n==0){
 8             return 1;
 9         }
10         if(n==1){
11             return 1;
12         }
13         int result = 0;
14         int r1=1;
15         int r2=1;
16         for(int i=2;i<=n;i++){
17             result= r1 + r2;
18             r1=r2;
19             r2=result;
20         }
21         return result;
22     }
23 
24 }

 

内容来源于网络如有侵权请私信删除
你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!