首页 > 其他分享 >零一背包与完全背包

零一背包与完全背包

时间:2023-08-06 18:11:27浏览次数:29  
标签:零一 背包 int 完全 weights 物品 values dp

零一背包

给定一组物品,每个物品有自己的重量和价值,以及一个背包的容量。目标是选择一些物品放入背包中,使得在不超过背包容量的情况下,背包中物品的总价值最大化。

思路

1、定义问题dp[i][j]:表示前i个物品中当容量为j时的最大价值

2、定义状态转移方程

(1) Dp[i][j] = math.max(dp[i][j-1], values[i] + dp[i - 1][j - weights[i]])

(2) 表示:如果放则为values[i] + dp[i - 1][j - weights[i]],如果不放则为之前计算好且容量为j-1时的最优解

3、定义初始值:dp[i][j]初始化为0,表示不放入物品时,背包的最大价值为0

 

代码

 

public class ZeroOneKnapsack {

    public static int knapsack(int[] weights, int[] values, int capacity) {
        int n = weights.length;
        int[][] dp = new int[n+1][capacity+1];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= capacity; j++) {
                if (weights[i-1] <= j) {
                    dp[i][j] = Math.max(values[i-1] + dp[i-1][j-weights[i-1]], dp[i-1][j]);
                } else {
                    dp[i][j] = dp[i-1][j];
                }
            }
        }
        return dp[n][capacity];

    }

    public static void main(String[] args) {
        int[] weights = {2, 3, 4, 5};
        int[] values = {3, 4, 5, 6};
        int capacity = 8;
        int maxTotalValue = knapsack(weights, values, capacity);
        System.out.println("Maximum total value: " + maxTotalValue);
    }
}

 

完全背包

在完全背包问题中,同样有一个背包容量为C,以及一组物品,每个物品有自己的重量和价值。不同的是,每个物品可以选择无限次放入背包中。目标是选择物品放入背包中,使得在不超过背包容量的情况下,背包中物品的总价值最大化。

思路

1、定义问题dp[j]:表示容量为j时可放入的最大价值

2、定义状态转移方程:

(1) Dp[j] = max(dp[j], values[i] + dp[j - weights[i]])

(2) 表示如果不放则为之前定义好且容量为j时的最优解,如果放则为values[i] + dp[j - weights[i]]

3、定义初始值:

代码

public class UnboundedKnapsack {

    public static int knapsack(int[] weights, int[] values, int capacity) {
        int n = weights.length;
        int[] dp = new int[capacity+1];

        for (int i = 0; i <= capacity; i++) {
            for (int j = 0; j < n; j++) {
                if (weights[j] <= i) {
                    dp[i] = Math.max(dp[i], values[j] + dp[i-weights[j]]);
                }
            }
        }
        return dp[capacity];
    }


    public static void main(String[] args) {
        int[] weights = {2, 3, 4, 5};
        int[] values = {3, 4, 5, 6};
        int capacity = 8;
        int maxTotalValue = knapsack(weights, values, capacity);
        System.out.println("Maximum total value: " + maxTotalValue);
    }

}

总结

零一背包与完全背包的max区别在于不放时的场景

(1) 零一背包:dp[i-1][j]表示不放那就最大值依赖于前i-1个物品的最大值

(2) 完全背包:dp[i]表示不放那就依赖于之前已经计算好的容量为i时的最优解

标签:零一,背包,int,完全,weights,物品,values,dp
From: https://www.cnblogs.com/Adam-Ye/p/17609688.html

相关文章

  • 多重背包 (单调队列)
    题目链接#include<bits/stdc++.h>usingll=longlong;constintN=1E3+5,M=2E4+5;intn,m;intv[N],w[N],s[N];intf[M];intl,r,q[M];intcalc(inti,intu,intk){ returnf[k*v[i]+u]-k*w[i];}intmain(){ std::ios::sync_with_......
  • Hadoop完全分布式集群安装
    Hadoop完全分布式集群安装使用版本:hadoop-3.2.0安装VMware看一下这张图,图里面表示是三个节点,左边这一个是主节点,右边的两个是从节点,hadoop集群是支持主从架构的。不同节点上面启动的进程默认是不一样的。下面我们就根据图中的规划实现一个一主两从的hadoop集群安装hado......
  • 总结: [01背包] 空间优化后内层循环为啥是逆序的?
    总结:[01背包] 空间优化后内层循环为啥是逆序的?首先,这是一个困扰了不少人的问题,虽然网上有挺多的解释,但是有的想起来比较费劲,于是乎,就有了这篇题解题目分析首先,01背包问题是一个非常非常非常经典的动态规划问题(后文简称“动规”或“dp”)。 因为百度百科上的题目分析......
  • [算法学习笔记] 多重背包--二进制拆分
    多重背包回顾一下多重背包是什么?有\(n\)种物品,每个物品都有有限个,每个物品都有重量和价值两个参数,你有一个限重为\(W\)的背包,求背包内价值最大。我们朴素的做法是将多重背包拆分成01背包求解,因为每个物品都有有限个,假设第\(i\)个物品有\(j\)个,那么跑\(j\)次01背包即可。但是这......
  • Windows服务器Oracle11G完全卸载详细教程
    Windows服务器Oracle11G安装详细教程(附Oracle11g安装程序)......
  • 2799.统计完全子数组的数目-356
    统计完全子数组的数目给你一个由正整数组成的数组nums。如果数组中的某个子数组满足下述条件,则称之为完全子数组:子数组中不同元素的数目等于整个数组不同元素的数目。返回数组中完全子数组的数目。子数组是数组中的一个连续非空序列。示例1:输入:nums=[1,3,1,2......
  • 完全背包
    二维(一样爆内存)1for(inti=1;i<=n;i++)//完全背包可以重复装相同的物品2for(intj=0;j<=m;j++){3f[i][j]=f[i-1][j];4if(j-v[i]>=0)f[i][j]max(f[i][j],f[i][j-v[i]]+w[i]);5}一维1for(......
  • 力扣---6900. 统计完全子数组的数目
    给你一个由 正 整数组成的数组 nums 。如果数组中的某个子数组满足下述条件,则称之为 完全子数组 :子数组中 不同 元素的数目等于整个数组不同元素的数目。返回数组中 完全子数组 的数目。子数组 是数组中的一个连续非空序列。 示例1:输入:nums=[1,3,1,2,2]......
  • 背包问题
    引入有n个物品和一个容量为W的背包,每个物品有重量w{i}和价值v{i}两种属性,要求选若干物品放入背包使背包中物品的总价值最大且背包中物品的总重量不超过背包的容量。我们之后涉及到的所有背包问题都会根据这个背景展开1.01背包每个物品只能选取一次。这样每个物品......
  • 背包问题
    (1)01背包01背包二维#include<iostream>#include<algorithm>usingnamespacestd;constintN=1010;intn,m;intv[N],w[N];//v保存体积,w保存价值intf[N][N];//保存所有集合最值状态intmain(){cin>>n>>m;for(inti=1;i<=n......