zoukankan      html  css  js  c++  java
  • 简单易懂动态规划算法

    什么是动态规划

    把原问题分解成若干个相对简单的子问题,然后逐步解决子问题从而解决复杂问题的方法。动态规划常常适用于有重叠子问题和最优子结构性质的问题。

    基本思想

    若要解出一个相对复杂的问题,我们需要解出其子问题,再合并子问题从而得到原问题的解。

    问题特征

    最优子结构:当原问题最优解包含了其子问题的最优解时,称该问题具有最优子结构。

    重叠子问题:在用递归算法自顶向下解问题时,每次产生的子问题并不总是新问题,有些子问题被反复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只解一次,而后将其解保存在一个表格中,在以后尽可能多地利用这些子问题的解。

    分治与动态规划

    共同点:二者都要求原问题具有最优子结构性质,都是将原问题分而治之,分解成若干个规模较小(小到很容易解决的程序)的子问题.然后将子问题的解合并,形成原问题的解.

    不同点:分治法将分解后的子问题看成相互独立的,通过用递归来做。

         动态规划将分解后的子问题理解为相互间有联系,有重叠部分,需要记忆,通常用迭代来做。

    递归和迭代定义

    相同点:

    递归和迭代都是循环的一种。

    不同点:

          1、程序结构不同

    递归是重复调用函数自身实现循环。

    迭代是函数内某段代码实现循环。

    其中,迭代与普通循环的区别是:迭代时,循环代码中参与运算的变量同时是保存结果的变量,当前保存的结果作为下一次循环计算的初始值。

          2、算法结束方式不同

     递归循环中,遇到满足终止条件的情况时逐层返回来结束。

    迭代则使用计数器结束循环。

      当然很多情况都是多种循环混合采用,这要根据具体需求。

          3、效率不同

    在循环的次数较大的时候,迭代的效率明显高于递归。

    动态规划的解决步骤

    1. 判断题意是否为找出一个问题的最优解
    2. 从上往下分析问题,大问题可以分解成子问题,子问题还有更小的子问题
    3. 从下往上分析问题,找出这些问题之间的关联(状态转移方程)
    4. 讨论底层的边界问题
    5. 解决问题(通常使用数组进行迭代求出最优解)

    例题:找最长回文子串

    给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

    示例 1:

    输入: "babad"

    输出: "bab"

    注意: "aba" 也是一个有效答案。

    示例 2:

    输入: "cbbd"

    输出: "bb"

    /*使用动态规划
         * 步骤1:找到状态转移函数
         * 步骤2:找到底界问题两种情况(第一种是最中间是一个字母,第二种是最中间相邻相同)
         * 步骤3:解决问题
         */    
    class Solution {
        public String longestPalindrome(String s) {
            if(s.equals(""))
        {
            return "";
        }
        String temp=String.valueOf(s.charAt(0));
        //第一种
        for(int i=0;i<s.length();i++)
        {
             for(int j_min=i-1,j_max=i+1;j_min>=0&&j_max<s.length();j_min--,j_max++)
             {
                 if(String.valueOf(s.charAt(j_min)).equals(String.valueOf(s.charAt(j_max))))
                 {
                     if(temp.length()<(j_max-j_min+1))
                     {
                         temp=s.substring(j_min, j_max+1);
                     }
                    
                 } else break;
              }
            }
        //第二种
        for(int i=0,j=1;i<s.length()&&j<s.length();i++,j++)
        {
             for(int j_min=i,j_max=j;j_min>=0&&j_max<s.length();j_min--,j_max++)
             {
                 if(String.valueOf(s.charAt(j_min)).equals(String.valueOf(s.charAt(j_max))))
                 {
                     if(temp.length()<(j_max-j_min+1))
                     {
                         temp=s.substring(j_min, j_max+1);
                     }
                    
                 } else break;
              }
            }
                  return temp;
            
        }
    }

     

  • 相关阅读:
    js怎样生成json的数据
    JS中生成与解析JSON
    [转]js动态创建json类型
    handlebars模板库的资源
    一指流沙,倾覆了谁的年华?
    c# const与readonly 关键字的比较
    静态类和静态构造函数
    编写跨浏览器兼容的 CSS 代码的金科玉律
    mysql 分页sql
    EF报LINQ to Entities 不识别方法“Web_JZRepository.Models.copy_materials_details get_Item(Int32) ”,因此该方法无法转换为存储表达式。
  • 原文地址:https://www.cnblogs.com/xiaobaidashu/p/10686206.html
Copyright © 2011-2022 走看看