Day1_背包问题+完全背包问题

   今天学习了背包、完全背包问题(一类新接触的算法),以初学者的视角,听了y总的课有点小模糊,又去b站找了些具象化的视频资源,大概了解一些,现在顺便总结一下。

1.背包问题

   题目描述

有 N件物品和一个容量是 V的背包。每件物品只能使用一次。

第 i 件物品的体积是 vi,价值是 wi。

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。

  属于动态规划问题。

f[i][j]:      表示前i个物品的总体积不超过j的最大价值。

package simple;
import java.util.*;
public class dp {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        final int N = 1010;
        //首次初始化,体积和价值数组
        int[] v = new int[N];//存储每个物体的体积
        int[] w = new int[N];//存储每个物体的价值
        //f[i][j]存储前i个物品的总体积为j的最大价值;
        int [][] f = new int[N][N];
        int n = sc.nextInt();//总共的物品数量
        int m = sc.nextInt();//总共的背包容量
        for(int i = 1;i <= n;i++){//初始化1~n个物品的体积和价值
            v[i] = sc.nextInt();
            w[i] = sc.nextInt();
        }
        //DP核心代码
        //会更新f[i][j]  
        for(int i = 1 ; i <= n; i++){
            for(int j = 0 ; j <= m; j++){
                f[i][j] = f[i - 1][j];
                if( j >= v[i]){
                    f[i][j] = Math.max(f[i - 1][j],f[i - 1][j - v[i]] + w[i]);
                }
            }
        }
        System.out.println(f[n][m]);
    }
    }
之后又去b站看了图像解释

①解释行列含义:每行表示不同的物品,例如第一行,一颗葡萄(2,3)表示体积为2,价值为3,以此类推。每列表示不同背包的容量大小,例如给定最大容量为6,那么就可以列出0~6共7列。

②初始化:第零行为0,因为无物品,那么对应的背包中的价值就为0;第一列为0是因为背包容量为0就装不下物品,所以其价值自然就为0;

③:一般性初始化,对于f[1][1],表示前1个物体(葡萄)总体积不超过1的最大价值,分两类情况,第一类:将第1个物品装入背包,第二类,不装第1个物品,而装前1个物品(第0个),最后将二者中的最大值付给f[i][j],保证每个位置上都是最优解。

首先考虑葡萄的体积与当前背包的体积,2 > 1,体积为1的背包不能容纳体积为2的葡萄,(第一类)所以考虑将第0个装此背包,即f[1][1] = f[0][1];  对于f[1][2],葡萄体积(2)= 背包体积(2),考虑情况1,将第1个物品装入背包,此时价值为3;第二类情况,不装第1个,只装前1个(第零个),其价值为f[0][1] = 0 ;此时比较两种价值,可得第一类背包价值的更大,所以,f[1][2] = 3;

其余情况以此类推:注意按行将表格补充完整。

  完全背包问题与背包问题的区别就在于:背包问题,每个物品仅限使用一次;对于完全背包问题:物品可以无限量使用。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值