动态规划

慨念

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


动态规划关键

1、最优子结构
2、边界
3、状态转换方程式

例子

从斐波那契数列的式子出发

 F(1)=1  当n=1时(边界)
 F(2)=1  当n=2时(边界)
 F(n)=F(n-1)+F(n-2)  当n>3时(状态转换方程式)

但是会有以下问题,看下图
在这里插入图片描述
时间复杂度很高,是O(2^n),树中很多的要求的值重复了
在这里插入图片描述
颜色相同的式子重复了,那我们可以利用一个map中的key不重复来存储F(n),value来存储其值,这样时间复杂度就会减少到O(n),(代码如下)但是空间会消耗很大,再分析一下
在这里插入图片描述
看回来方程,F(n)=F(n-1)+F(n-2) 想要推导出想要的值,只要知道前两个值就OK了
故代码:

  int dynamic(int n){
     if (n<0){return 0;}
     if (n==1){return 1;}
     if (n==2){return 1;}

     int i=1;
     int j=1;
     int temp=0;

     for (int a=3;a<=n;a++){
         temp=i+j;
         i=j;
         j=temp;
     }
     return temp;

    }

例子二———数组中不相邻元素相加最大

例如如下数组
int arr[]={3,1,3,5}

有如下条件:

1、相加元素不能相邻
2、得出元素最大值

分析其中最优子结构:当我选择arr[3]时,该数组的最优最大值是F(3)=arr[3]+F(1),否则是 F(2)
也就是说,可以总结出这样的规律来
最优解是 MAX(arr[3]+F(1),F(2))
以此类推得出最优子结构:
F(3)=MAX(arr[3]+F(1),F(2))
然后,边界值也很容易出来就是F(0),F(1),容易得出F(0)=arr[0],F(1)=MAX(arr[1],arr[0])
得出状态转换方程:
F(0)=arr[0] n=0时
F(1)=MAX(arr[1],arr[0]) n=1时
F(n)=MAX(F(n-2)+arr[n], F(n-1)) n>=2时
故代码为:

int dynamic_dp(int []arr){
        int [] results=new int[arr.length];
        results[0]=arr[0];
        results[1]=Math.max(arr[0],arr[1]);

        for (int i=2;i<results.length;i++){
            int a=results[i-1];
            int b=results[i-2]+arr[i];
            results[i]=Math.max(a,b);
        }
        return results[arr.length-1];
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值