动态规划

什么是动态规划?

不论是贪婪或者dp等等本质实际上就是为了化繁为简也就是为了降低时间复杂度,而其中贪婪一般是面对npc问题一种近似算法不一定能获取最优解但是完美是优秀的敌人,在时间复杂度为2^N的情况下我们需要的就是降低时间成本为多项式函数。

而dp的理念便是如此,把一个大的复杂的问题分解成一个个小问题,注意的是小问题和大问题直接必须存在关联。dp很关键的理解就是空间换取时间。例子说明把

经典的剪绳子问题:

  给你一根长度为n的绳子,请把绳子剪成m段 (m和n都是整数,n>1并且m>1)每段绳子的长度记为k[0],k[1],...,k[m].请问k[0]*k[1]*...*k[m]可能的最大乘积是多少?

首先边界分析,如果f1 =0,f2 =1,f3=2 ,f4=max{f1*f3,f2*f2}=4,很显然可以看出来1米2米3米的绳子已经是最小原子了在分没意义了,如果绳子长于3米的话,剪一刀其中一边是 1 2 3这样的那么显然我们不会在去减他了,另一边显然是fn-1,fn-2,fn-3,减一米这个想法太蠢了我们略过把,实际只分析 2*fn-2 ,3*fn-3,现在问题已经很明然了前面两者中的优解便是最优解了。

那么fn-2 ,fn-3是子问题,fn是大问题,从f0....到fn ,我们保存了每项的最优解(自上而下递归最优解),直接用子问题的最优解来算出最优解。

下面的demo我只忽略减出一米这个无用过程,可以按上面的逻辑优化掉无用过程比如 10 拆解 5 *5这个流程是无用的,因为5并不是原子性,他自身不是最大值(最优解),另外边界代码也不写了大家都懂。

 

这些介绍说明比较好的:https://blog.csdn.net/upupday19/article/details/79315885

https://www.zhihu.com/question/39948290

public static int testCut(int length){
        int maxp[] = new int[length+1];
        maxp [1] = 1;
        maxp [2] = 2;
        maxp [3] = 3;
        int num = 0;
        for(int i=4;i<=length;i++){
            for (int j =2;j<=i/2;j++){
                int ls = maxp[j] * maxp[i -j];
                num = ls > num? ls : num;
            }
            maxp[i] = num ;
        }
        return maxp[length];
    }
上一篇:[SCOI2010] 股票交易(单调队列优化DP)


下一篇:最大后验与最大似然