zoukankan      html  css  js  c++  java
  • 深入理解动态规划DP

    通过最近对于一些算法题的思考,越来越发现动态规划方法的在时间上高效性,往往该问题可以轻松的找到暴力破解的方法,其时间复杂度却不尽人意。下面来看看几个常见的动态规划思路的经典问题

    例一.有一段楼梯有10级台阶,规定每一步只能跨一级或两级,要登上第10级台阶有几种不同的走法?(腾讯电面题之一)
    其状态转移方程为:

    f(n):n
    f(n)=f(n1)+f(n2)
    f(1)=1,f(2)=2

    例二:01背包问题
    有n个重量和价值分别为vector weight, vector value的物品;背包最大负重为W,求能用背包装下的物品的最大价值?
    输入:n =4
    weight=2, 1, 3, 2
    value =3, 2, 4, 2
    W=5
    输出=7

    dp[i][j]ij
    dp[i][j]=max(dp[i1][j],dp[i1][jw[i]]+v[i]);

    例三:最大连续子序列和
    如给定数组[-2,1,-3,4,-1,2,1,-5,4]
    连续的子数组为[4,-1,2,1]有最大和6
    f(j+1)j
    f(j+1)=max(f(j)+A[j],A[j])
    target=maxf[j]

    思考:最大连续子序列乘积
    如给定数组[-2,1,-3,4,-1,2,1,-5,4]
    连续的子数组为[4,-1,2,1]有最大和6
    f(j+1)j1

    状态转移方程如何表示呢:
    这里我们知道A[j]可能为正数(或0)或负数,那么当A[j]为正数,期望前j个乘积为正数,若为负数,则期望前面的为负数。故我们需定义两个函数来确定我们的状态转移方程:
    fmax(j+1)=max(max(fmax(j)A[j],A[j]),fmin(j)A[j])
    fmin(j+1)=min(min(fmin(j)A[j],A[j]),fmax(j)A[j])(2)

    1.通过以上动态问题问题的分析,可以看出最重要的是定义好相应的问题,然后写出状态转移方程,往往这也是整个问题求解最能考察你分析能力的过程。能够用动态规划求解的问题有两类性质:
    a.重叠子问题

    采用递推方式,比如上例要求出10阶楼梯走法,那么最后一步是踏一步上来或者踏2步上来,最后转化为相应的子问题,子问题深入求解就包含了重叠的子问题,所以自顶向下的实现并不高效,常采用备忘录方式保存子问题的最优解,自底向上更高效。

    b.最优子结构:
    往往子问题的最优解可以推出原问题的最优解

  • 相关阅读:
    Winform中在ZedGraph中最多可以添加多少条曲线(转)
    c#委托的含义和用法
    vs2010打开vs2017工程
    C# Socket编程资源
    C# 调用打印机 打印 Excel (转)
    NPOI 教程
    C# 调用C++ DLL 的类型转换(转载版)(转)
    进程间通信(网络阅读笔记)
    NPOI 第二篇 设置样式与合并单元格(转)
    分布式事务的 6 种解决方案,写得非常好!
  • 原文地址:https://www.cnblogs.com/freeopen/p/5483026.html
Copyright © 2011-2022 走看看