• 【学习笔记】dp入门


    知识点

    动态规划(简称dp),可以说是各种程序设计中遇到的第一个坎吧,这篇博文是我对dp的一点点理解,希望可以帮助更多人dp入门。

     

    先看看这段话

    动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法。20世纪50年代初美国数学家R.E.Bellman等人在研究多阶段决策过程(multistep decision process)的优化问题时,提出了著名的最优化原理(principle of optimality),把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解,创立了解决这类过程优化问题的新方法——动态规划。1957年出版了他的名著《Dynamic Programming》,这是该领域的第一本著作。

    这是百度百科上对于动态规划介绍,其实dp并没有这么复杂,可以把dp看作是记忆化搜索的递推形式。

    再来看一下下面这段文字(来自《挑战程序设计竞赛(第二版)》):

    就像上面所说的,对于一道题目,如果选择搜索可能会出现大量重复的状态,如函数f

     int f(int a,int b)
     {
         return f(a+1,b+1)+f(a-1,b-1);
     }

    这种函数在计算过程中有大量的资源被浪费,如 f(1,1) 和 f(3,3) 在返回值时都会计算一次 f(2,2),这种无谓的计算致使了动态规划的诞生。

    动态规划算法通常基于一个递推公式及一个或多个初始状态。当前子问题的解将由上一次子问题的解推出。使用动态规划来解题只需要多项式时间复杂度,因此它比回溯法、暴力法等要快许多。

    现在让我们通过一个例子来了解一下DP的基本原理。

    首先,我们要找到某个状态的最优解,然后在它的帮助下,找到下一个状态的最优解。

    (上面这段话看不懂也就别看了)

     其实简单的来说,dp就是用数组来递推下一个状态。

    像上面的f函数,写成dp就是 f[a][b] 。递推式也与函数基本相同:f[a][b]=f[a-1][b-1]+f[a+1][b+1]。用这个式子,双重循环即可。


     

    例题

    如下是几个经典问题,对于初学者来说有一点点难度,不懂可以多看几篇关于dp入门的文章。此处附上我的代码。题目可以百度。

    最好要理解,并能独立实现代码

    1、01背包

    View Code

    2、最长上升子序列(简称LIS,两种做法,一种是O(n2),另一种是O(nlogn))

    View Code

    3、最长公共子序列(简称LCS)

    View Code


    看完了上面的,可以做做题练练手了。

    下面是一些题目的练习,题目都在www.luogu.org上,可以配合里面的题解与我的代码来理解。


    习题

    下述题目都为基础的dp包括经典问题与其各种变形,乃dp入门必备之题。

    注意: 1、从最下面往上刷


     最后提供一些练习题与详解:传送门

    刷完了进入下一章:dp基础

    洛谷P1280 尼克的任务

    逆序dp,详见注释

    View Code

    洛谷P1091 合唱队形

    从头开始,从尾开始各跑一次LIS

    View Code

    洛谷P1115 最大子段和 dp

    View Code

    洛谷P1508 Likecloud-吃、吃、吃

    View Code

    洛谷P1510 精卫填海

    View Code

    洛谷P1855 榨取kkksc03

    View Code

     

    洛谷P1216 [USACO1.5]数字三角形 Number Triangles

    View Code

     洛谷P1910 L国的战斗之间谍

    View Code

    洛谷P2925 [USACO08DEC]干草出售Hay For Sale

    View Code

    洛谷P2347 砝码称重

    View Code

    洛谷P2722 总分 Score Inflation

    View Code

    开始dp入门的征程吧! 

    ------------------------------------------------------------------------------------------

    后继章:dp基础

  • 相关阅读:
    java中的锁
    CAS机制与自旋锁
    volatile关键字的特性及证明
    java中并发下的集合类
    数据库的分库分表
    浅入理解JVM
    99乘法表
    JAVA实现简单的时间刷新使用线程
    线程的优先级
    线程礼让
  • 原文地址:https://www.cnblogs.com/noblex/p/7624832.html
Copyright © 2020-2023  润新知