动态规划的学习

        动态规划的学习中,我们对比了斐波那契数与动态规划的区别,在代码上我们进行递归操作能实现一个斐波那契数列:

public static long feiBo(int n) {
    if (n == 1 || n == 2) {
        return 1;
    }
    return feiBo(n - 1) + feiBo(n - 2);
}

在使用时,我们很清楚的发现,在计算一些较大的位置的值时,其返回速度相当的满,原因在于在计算一个数时,他一直在计算每一个小的值,当所有的都计算玩之后才能返回结果。在学习时,我们将这段代码进行简单的修改就将这个性能各提上来了:

public static long feiBo(int n, long[] arr) {
    if (n == 1 || n == 2) { 
        return 1; 
    }
    if (arr[n - 1] == 0) {
        arr[n - 1] = feiBo(n - 1, arr) + feiBo(n - 2, arr);
    }
    return arr[n - 1];
}

对比于前面的代码,我们只进行了一个操作,就是用一个数组,进行保存每次计算完后的结果,在使用时,返回数组的下标就能快速的知道结果。

由此引出:动态规划的使用特点:

        1、状态的保存

        2、状态转移方程。

在动态规划中,经典的问题时背包问题,大致意思是:如何将背包空间利用起来,达到里面物品价值的最大化。简单举个例子 :

书包可装:5kg    

物品    重量    价值

   书       4          4

铅笔盒   2          6

   零食    1          7

    在几个物品中,我们对书包进行装配最大价值为:13元 ,是铅笔和加零食的组合。

这里是进行小数目的,我们可以很直观的判断最大价值,在大数量下,我们还是不能够简单找到。所以这就体现动态规划的价值,我们对每个位置的判断都进行记录,在进行比较时,我们要判断的是:

 在该重量下的价值与

减去当前物品下的最大价值加上物品价值

进行比较,如果大于,就将大的值记录下来,方便之后的比较,就这样反复进行,最后我们能得到最大的价值。

代码实现为:

public static int cal(int[] wight, int[] value, int body) {

    int[][] maxValue = new int[value.length][body + 1]; //构建一个二维数组。
    for (int i = value[0]; i <= body; i++) {
        maxValue[0][i] = value[0];
    }

    for (int i = 1; i < value.length; i++) {
        for (int j = 1; j <= body; j++) {
            if (j < wight[i]) {
                maxValue[i][j] = maxValue[i - 1][j];
            } else {
                maxValue[i][j] = Math.max(maxValue[i - 1][j], maxValue[i - 1][j - wight[i]] + value[i]);
            }
        }
    }
    for (int[] b : maxValue) {
        System.out.println(Arrays.toString(b));
    }
    return maxValue[value.length - 1][body];

}

在进行了该算法之后,给我的启发是:

在进行大量的运算时,我们可以考虑将已经计算过的数进行保存,减少运算中的重复计算,提高程序的执行效率。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值