zoukankan      html  css  js  c++  java
  • 动态规划算法的套路,动态规划入门

    前言:”与其每天担心未来,不如努力现在。别对自己丧失信心,成长的路上,只有奋斗才能给你最大的安全感“
    你好,我是梦阳辰,让我们一起加油,一起努力吧!

    在这里插入图片描述

    1. 动态规划解决的问题

    • 动态规划解决递归算法大量的冗余计算,递归算法时自顶向下思想,中间有太多重复计算,而动态规划自底向上递推求解,用表(通常为数组)记录子问题的解,以便保存和以后的检索,从最简单的问题的解填起,以自底向上的方式填表,这就保证了当我们求解一个子问题的时候,所有的与子问题相关子子问题,都可以从表中直接取用,不必重复计算。即用空间换取时间。但是,对于计算问题的解,还需利用递归公式。
    • 动态规划的由来:
      由于20世纪40年代末期,还没有出现计算机,这个动态填表的方法称为动态规划。

    2.动态规划的算法思想

    • 动态规划的思想的历史由来:

    在这里插入图片描述

    • 动态规划的总体思想:
      动态规划算法与分治算法类似,其基本思想也是将待求解的问题分解成若干子问题,先求解子问题,再从子问题的解得到原问题的解。在用分治法求解时,有些子问题被重复计算了许多次。而动态规划保存已解决的子问题的答案,而在需要时再找出以求得的答案,就可以避免大量的重复计算,从而得到多项式时间算法。
    • 动态规划用一个表来记录所有已解决的子问题的答案,具体的动态规划算法是多种多样的,但它们具有相同的填表方式。
    • 分治算法的特征在这里插入图片描述
    • 如果不具备第三条特征,则可以考虑贪心算法或动态规划。

    3.动态规划的基本步骤

    • 1.找出最优解的性质并刻划其结构特征
    • 2.递归的定义最优值
    • 3.以自底向上的方式计算出最优值
    • 4.根据计算最优值得到的信息构造最优解(有时可以省略)

    动态规划特点:
    在这里插入图片描述

    4.经典例题讲解

    • 题目一:机器人一次可以走1m,2m或3m。编写一个动态规划算法求机器人走n米有多少种走法。
      递归求解:
    #include<stdio.h>
    #define N 4
    int robotSteps(int n){
    	if(n==1||n==0)
    		return 1;
    	else if(n==2)
    		return 2;
    	else return robotSteps(n-1)+robotSteps(n-2)+robotSteps(n-3);
    }
    int main(){
    	int n;
    	printf("一共有%d种走法!
    ",robotSteps(N));
    	return 0;
    }
    
    

    动态规划求解:

    #include<stdio.h>
    #define N 4
    int robotSteps(int n){
    	int i,arr[N+1];
    	arr[1]=1;
    	arr[2]=2;
    	arr[3]=4;
    	for(i=4;i<n+1;i++){
    		arr[i]=arr[i-1]+arr[i-2]+arr[i-3];
    	}
    
    return arr[n];
    }
    int main(){
    	int n;
    	printf("一共有%d种走法!
    ",robotSteps(N));
    	return 0;
    }
    
    
    • 题目二:
      在这里插入图片描述
      在这里插入图片描述
      子问题:列出所有情况可能出现的最优子结构,在将这些情况找出最优子结构。
      在这里插入图片描述
      递归解法:
      在这里插入图片描述
      递归求解重复计算太多。
    • 动态规划解决这个问题。
      1.转移方程
      在这里插入图片描述
      加一表示要一个硬币。
      2.初始条件和边界情况
      在这里插入图片描述
      初始条件:就是用转移方程算不出来的,需要手工定义。
      3.计算顺序
      自顶向上,要让要求得问题,其子问题都被求过。
      在这里插入图片描述
      在这里插入图片描述
    public static int coinChange(int []A,int M) {
    	int [] f =new int[M+1];
    	int n = A.length;
    	f[0]= 0;
    	int i,j;
    	for(i=1;i<=M;++i) {
    		f[i]=Integer.MAX_VALUE;
    		for(j=0;j<n;++j) {
    			if(i>=A[j]&&f[i-A[j]]!=Integer.MAX_VALUE) {
    				f[i]=Math.min(f[i]-A[j]+1,f[i]);
    			}
    			}
    				
    		
    	}
    	if(f[M]==Integer.MAX_VALUE) {
    		f[M]=-1;
    	}
    	return f[M];
    
    • 题目三(计数问题)
      在这里插入图片描述
      计算顺序:
      在这里插入图片描述
      在这里插入图片描述
    • 题目四(存在型)
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    轻松搞定动态规划解决矩阵连乘问题
    关注公众号【轻松玩编程】,回复“计算机资源”,“Java从入门到进阶”,获取更多学习资源!

    在这里插入图片描述

    以梦为马,不负韶华。
  • 相关阅读:
    一阶倒立摆分析
    用Matlab进行部分分式展开
    2013/07/11 中科院软件所就业讲座总结
    解决vs2010“创建或打开C++浏览数据库文件 发生错误”的问题 Microsoft SQL Server Compact 3.5
    centos安装
    Mongodb——GridFS
    MongoDB—— 写操作 Core MongoDB Operations (CRUD)
    MongoDB—— 读操作 Core MongoDB Operations (CRUD)
    数据库
    影像数据库调研
  • 原文地址:https://www.cnblogs.com/huangjiahuan1314520/p/12804250.html
Copyright © 2011-2022 走看看