十大常用算法之动态规划(java版)

十大常用算法的完整实现

一、二分查找算法:https://blog.csdn.net/weixin_46635575/article/details/121532149
二、分治算法:https://blog.csdn.net/weixin_46635575/article/details/121532941
三、动态规划算法:https://blog.csdn.net/weixin_46635575/article/details/121534074
四、KMP算法:https://blog.csdn.net/weixin_46635575/article/details/121590510
五、贪心算法:https://blog.csdn.net/weixin_46635575/article/details/121626626
六、普利姆算法:https://blog.csdn.net/weixin_46635575/article/details/121653256
七、克鲁斯卡尔算法:https://blog.csdn.net/weixin_46635575/article/details/121670374
八、地杰斯特拉算法:https://blog.csdn.net/weixin_46635575/article/details/121692675
九、佛洛依德算法:https://blog.csdn.net/weixin_46635575/article/details/121714678
十、马踏棋盘算法(周游骑士算法):https://blog.csdn.net/weixin_46635575/article/details/121716596

1、动态规划介绍

1、背包问题
在这里插入图片描述
2、动态规划介绍

在这里插入图片描述

2、动态规划案例演示(背包问题)

(1)背包问题描述

  • 问题描述
    在这里插入图片描述

分析一波背包问题

  • 物品
    在这里插入图片描述
  • 解决思路
    在这里插入图片描述
  • 具体步骤
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 得到的一个结果
    在这里插入图片描述
    在这里插入图片描述
    验证两个数值
    在这里插入图片描述
    上面看不懂就接下来好好看代码

(2)背包问题代码实现

package cn.mldn.kp;


public interface KnapsackProblem {
    public static void main(String[] args) {
        /*第一步*/
        //建数组来保存物品的重量
        int[] w = {1,4,3};
        //物品的价格
        int[] val = {1500,3000,2000};//val[i]就表示之前的v[i]
        int m = 4;//背包的大小
        int n = val.length;//物品的个数

        //创建二维数组,v[i][j]表示在前i个物品中能够装入容量为j的背包中的最大价值
        int[][] v = new int[n + 1][m + 1];
        //初始化第一行第一列
        for (int i = 0; i < v.length; i++) {
            v[i][0] = 0;//把第一列设置为0
        }
        for (int j = 0; j < v[0].length; j++) {
            v[0][j] = 0;//第一列
        }

        //输出一把
        for (int i = 0; i < v.length; i++) {
            for (int j = 0; j < v[i].length; j++) {
                System.out.print(v[i][j] + " ");
            }
            System.out.println();
        }

        /*第二步*/
        //根据之前的推导的公式来分析
        for (int i = 1; i < v.length; i++) {//不处理第一行
            for (int j = 1; j < v[0].length; j++) {//不处理第一列
                if (w[i - 1] > j) {//因为我们程序i是从1开始的,因此我们要从原理的基础上减1
                    v[i][j] = v[i - 1][j];
                } else {
                    //因为我们i是从1开始的,同样的道理要进行调整
                    v[i][j] = Math.max(v[i-1][j],val[i-1] + v[i-1][j-w[i-1]]);//同样的道理,这里的i也要减一个1
                }
            }
        }

        //输出一把
        System.out.println("________________________________________________________");
        for (int i = 0; i < v.length; i++) {
            for (int j = 0; j < v[i].length; j++) {
                System.out.print(v[i][j] + " ");
            }
            System.out.println();
        }



        /*第三步*/
        //为了能记录商品的放置情况,定义一个二维数组
        int[][] path = new int[n + 1][m + 1];

        for (int i = 1; i < v.length; i++) {//不处理第一行
            for (int j = 1; j < v[0].length; j++) {//不处理第一列
                if (w[i - 1] > j) {//因为我们程序i是从1开始的,因此我们要从原理的基础上减1
                    v[i][j] = v[i - 1][j];
                } else {
                    if (v[i-1][j] < val[i-1] + v[i-1][j - w[i-1]]) {
                        v[i][j] = Math.max(v[i-1][j],val[i-1] + v[i-1][j-w[i-1]]);//同样的道理,这里的i也要减一个1
                        //记录一下
                        path[i][j] = 1;
                    } else {
                        v[i][j] = Math.max(v[i-1][j],val[i-1] + v[i-1][j-w[i-1]]);//同样的道理,这里的i也要减一个1
                    }
                }
            }
        }

        //输出一把
        System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        for (int i = 0; i < v.length; i++) {
            for (int j = 0; j < v[i].length; j++) {
                System.out.print(v[i][j] + " ");
            }
            System.out.println();
        }
        //看一下我们有几个数据放入到其中了
        int i = path.length - 1;//行的最大下标
        int j = path[0].length - 1;//列的最大下标
        while (i > 0) {//从path的最后开始找
            if (path[i][j] == 1) {
                System.out.printf("第%d个商品被放到背包里面\n" , i);
                j -= w[i - 1];
            }
            i --;
        }

    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值