算法学习:Java实现背包问题

1、0-1背包问题

物品重量价格
吉他11500
音响43000
电脑32000

背包的填表过程:

       

物品\重量0磅1磅2磅3磅4磅
00000
吉他01500150015001500
音响01500150015003000
电脑01500150020002000+1500=3500

代码实现如下(两种方式:一纬数组和二维数组) 

public class Main {


    public static void main(String[] args) {
        int totalweight = 4;
        int values[] = {1500, 3000, 2000};
        int weights[] = {1, 4, 3};
        System.out.println(bag(totalweight,weights,values));
        System.out.println(bag01(totalweight, weights, values));
    }


    //二维数组实现背包问题

    public static int bag(int totalV, int[] weights, int[] values) {
        if (weights == null || weights.length == 0) {
            return 0;
        }
        int n = weights.length;
        int m = totalV;
        //创建二维数组,v[i][j]表示在前i个物品中能够装入容量为j的背包中的最大价值
        int[][] v = new int[n + 1][m + 1];
        //初始化第一行和第一列,这里本程序可以不用处理,因为默认就是0
        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; //第一行设置为0
        }

        for (int i = 1; i < v.length; i++) {
            for (int j = 1; j < v[0].length; j++) {
                if (weights[i-1] > j) {//weights[i-1]表示第一件物品的重量
                    v[i][j] = v[i - 1][j];
                } else {
                    v[i][j]=Math.max(v[i-1][j],v[i-1][j-weights[i-1]]+values[i-1]);
                }
            }

        }

        return v[n][m];

    }

    //非递归一纬数组 totalV是背包的容量
    public static int bag01(int totalV, int[] weights, int[] values) {
        if (weights == null || weights.length == 0) {
            return 0;
        }
        int goodsNum = weights.length;
        int f[] = new int[totalV + 1];
        for (int i = 0; i < goodsNum; i++) {
            int w = weights[i];
            int v = values[i];
            for (int j = totalV; j >= w; j--) {
                f[j] = Math.max(f[j], f[j - w] + v);
                //f[j]表示:前i个物品放入容量为j的背包的最大价值
            }
        }
        return f[totalV];
    }
}

2、完全背包以及变种问题,请参考如下链接

动态规划---背包问题详解_无月可归的博客-CSDN博客

经典算法总结——背包问题(java实现)【已完结】_包里面装东西 算法_lanyu_01的博客-CSDN博客

人民币组合问题:算法笔试题:1元,5元,10元,20元,50元、100元面值人民币组合给定x元的问题_LarsCheng的博客-CSDN博客

最长公共子序列:

【算法学习】最长公共子序列(Java)_最长公共子序列算法java_鼠晓的博客-CSDN博客 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值