希尔排序 —— 自己的理解

本文介绍了一种解决背包问题的动态规划方法,并通过具体代码实现了该算法。展示了如何通过二维数组记录每一步的最佳选择来求解背包的最大价值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


/**
 * Created on 2021/7/1
 * 参考链接 https://www.cnblogs.com/kkbill/p/12081172.html
 * @Author ZFH
 */
public class BagQuestion1 {

    /**
     * 物品编号   1    2    3    4
     * 物品体积   2    3    4    5
     * 物品价值   3    4    5    6
     */
    static int[] weight = {0,2,3,4,5}; //物品体积
    static int[] value  = {0,3,4,5,6}; //物品价值
    static int bagWeight = 8;          //背包容量
    //定义V(i,j):当前背包容量 j,前 i 个物品最佳组合对应的价值
    static int[][] bagWeightTable = new int[5][9];  //动态规划表  第一个参数代表物品体积  第二个参数代表当前背包容量
    static int[] item = new int[weight.length];//存放最优解

    public static void main(String[] args) {
        // i 从 1 开始,要和 i - 1 作比较
        for (int i = 1; i <= weight.length - 1; i++) {
            // j 代表 当前背包容量
            for (int j = 1; j <= bagWeight ; j++) {
                //当 当前背包容量不足以容纳第 i 件 物品时
                if ( j < weight[i]){
                    //就等于没装
                    bagWeightTable[i][j] = bagWeightTable[i - 1][j];
                }else {
                    //装了也不一定是最优解,选最大的
                    //这里不好理解
                    //第一次第一行一个物品放进去产生了最大价值
                    //第二次第二行的物品要看当前背包容量放不放得下,放进去和之前比较哪个价值更大
                    //    bagWeightTable[i - 1][j] 代表同样背包容量下的价值
                    //    剩余空间的价值                          + 当前商品的价值
                    //    bagWeightTable[i - 1][j - weight[i]]  + value[i] 代表存放进去之后的价值
                    bagWeightTable[i][j] = Math.max(bagWeightTable[i - 1][j],bagWeightTable[i - 1][j - weight[i]] + value[i]);
                }
            }
        }

        findBest(4,8);
        //动态规划表的输出
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 9; j++) {
                System.out.print(bagWeightTable[i][j] + "  ");
            }
            System.out.println();
        }
        //最优解输出
        for (int i = 0; i < 5; i++)          //最优解输出
            System.out.print(item[i] + "  ");

    }

    //回溯  倒序
    private static void findBest(int i , int j){
        if ( i > 0 ){
            //如果相等,说明没把当前的加进去
            if (bagWeightTable[i][j] == bagWeightTable[i - 1][j]){
                item[i] = 0;
                //递归遍历当前容量之前的物品
                findBest(i - 1,j);
                //如果当前容量大于第i个物品的体积  且 价值等于把第i个物品加入进去之后的价值,说明当前是最优解
            }else if ((j - weight[i]) >= 0 && (bagWeightTable[i][j] == (bagWeightTable[i - 1][j - weight[i]] + value[i]))){
                item[i] = 1;
                findBest(i - 1,j - weight[i]);
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java天下第1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值