dp总结

原创 2016年05月31日 20:44:12

      首先动态规划是解决多阶段决策问题的一种方法。。


     动态规划本质上就是一种排除重复计算的算法,更具体的说,动态规划就是用空间换取时间。

   

   多阶段决策问题:如果一类问题的求解过程可以分为若干个互相联系的阶段,在每一个阶段都需作出决策,并影响到下一个阶段的决策。多阶段决策问题,就是要在可以选择的那些策略中间,选取一个最优策略,使在预定的标准下达到最好的效果.


    而最优性原理即不论初始状态和第一步决策是什么,余下的决策相对于前一次决策所产生的新状态,构成一个最优决策序列。最优决策序列的子序列,一定是局部最优决策子序列。包含有非局部最优的决策子序列,一定不是最优决策序列。。


    使用动态规划普遍比其他方法代码短,所以说如果一道题可以用dp解和遍历解,这时候一定要选dp。。


     那么如何判断选不选用dp呢?

      1:问题具有多阶段决策的特征。
      2:每一阶段都有相应的“状态”与之对应,描述状态的量称为“状态变量”。
      3:每一阶段都面临一个决策,选择不同的决策将会导致下一阶段不同的状态。
      4:每一阶段的最优解问题可以递归地归结为下一阶段各个可能状态的最优解问题,各子问题与原问题具有完全相同的结构

   

     而dp的一般解题思路分为下面几个步骤:

      1、判断问题是否具有最优子结构性质,若不具备则不能用动态规划。
      2、把问题分成若干个子问题(分阶段)。
      3、建立状态转移方程(递推公式)。
      4、找出边界条件。
      5、将已知边界值带入方程。
      6、递推求解。


    举几个经典例子。。

   最经典的莫过于最优子序列了,好多问题都是他的变形。。。


输入数据
输入的第一行是序列的长度N (1 <= N <= 1000)。第二行给出序列中的N 个整数,这些整数的取值范围都在0 到10000。
输出要求
最长上升子序列的长度。
输入样例
7
1 7 3 5 9 4 8
输出样例
4


如何把这个问题分解成子问题呢?经过分析,发现 “求以ak(k=1, 2, 3…N)为终点的最长上升子序列的长度”是个好的子问题。
 由上所述的子问题只和一个变量相关,就是数字的位置。因此序列中数的位置k 就是“状态”,而状态 k 对应的“值”,就是以ak 做为“终点”的最长上升子序列的长度。这个问题的状态一共有N 个。状态定义出来后,转移方程就不难想了。 

假定MaxLen (k)表示以ak 做为“终点”的最长上升子序列的长度,那么:
MaxLen (1) = 1
MaxLen (k) = Max { MaxLen (i):1<i < k 且 ai < ak 且 k≠1 } + 1
实际实现的时候,可以不必编写递归函数,因为从 MaxLen(1)就能推算出MaxLen(2),有了MaxLen(1)和MaxLen(2)就能推算出MaxLen(3)……

代码:

int b[MAX_N + 10];
int aMaxLen[MAX_N + 10];
int main()
{
    int i, j, N;
    scanf("%d", & N);
    for( i = 1;i <= N;i ++ )
        scanf("%d", & b[i]);
    aMaxLen[1] = 1;

 for( i = 2; i <= N; i ++ ) 
    { //求以第i 个数为终点的最长上升子序列的长度
        int nTmp = 0; //记录第i 个数左边子序列最大长度
        for( j = 1; j < i; j ++ ) 
        { //搜索以第i 个数左边数为终点的最长上升子序列长度
            if( b[i] > b[j] ) 
            {
                if( nTmp < aMaxLen[j] )
                    nTmp = aMaxLen[j];
            }
        }
        aMaxLen[i] = nTmp + 1;
    }

int nMax = -1;
    for( i = 1;i <= N;i ++ )
        if( nMax < aMaxLen[i])
            nMax = aMaxLen[i];
    printf("%d\n", nMax);
    return 0;
}


————————————————————————————————————————————————————————————————


然后还有的经典题就是斐波那契数列问题或是这类的变形。。。。f(n)=f(n-1)+f(n-2)。。

这种题我的博客里也有好多。。

不举例子了。。



————————————————————————————————————————————————————————————————


       7
      3 8
    8 1 0
   2 7 4 4 
  4 5 2 6 5

第三类经典的就是数塔类了。。。这种题的解题思路就是往上递推,不断的用max函数就可求出来了。。


————————————————————————————————————————————————————————————————

1  2  3  4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

然后还有一类我把它定位格子类,大概的就是从某一个点到另一个点求最大数。。


————————————————————————————————————————————————————————————————


先这些,以后想起来再补充。。

相关文章推荐

DP状态设计与方程总结

  • 2012年01月31日 20:14
  • 329KB
  • 下载

常见的DP优化类型总结

  • 2017年08月24日 02:47
  • 19KB
  • 下载

状态压缩DP总结【POJ3254】【POJ1185】【POJ3311】【HDU3001】【POJ2288】【ZOJ4257】【POJ2411】【HDU3681】

动态规划本来就很抽象,状态的设定和状态的转移都不好把握,而状态压缩的动态规划解决的就是那种状态很多,不容易用一般的方法表示的动态规划问题,这个就更加的难于把握了。难点在于以下几个方面:状态怎么压缩?压...
  • AcCry
  • AcCry
  • 2011年07月15日 10:10
  • 28488

ACM dp总结

  • 2012年10月20日 11:35
  • 159KB
  • 下载

dp算法总结

  • 2012年03月12日 13:26
  • 98KB
  • 下载

总结&备忘:android尺寸单位dp与mm

android ui设计中度量单位dp是什么 为什么要用dp 为什么不用mm

dp 背包问题(我自己总结的)

  • 2011年07月30日 13:36
  • 215KB
  • 下载

树形dp问题总结(转发)

  • 2010年12月14日 14:46
  • 203KB
  • 下载

区间DP(总结) & 石子合并

这位博主写的很详细   学长一晚上的耐心讲解,使我明白区间DP这么高级的东西,还是挺容易的。也就是在一段区间内的动态规划。   下面用例题进行总结。   例题:石子归并。   描述 有N堆石子排成一...

Dp_关于最大子矩阵的问题总结

我们知道子一行也是矩阵,只不过是特殊情况,首先来一道题,hdu 1506  高度h[i]  我们定义两个数组,分别为向左扩展能到的最左边的下标,和向右扩展能到的最右边的下标。 然后两个数组分别从正...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:dp总结
举报原因:
原因补充:

(最多只允许输入30个字)