笔试题目记录01背包

(题意略有改编,题意一致) 法外狂徒张三有n空间的口袋,要去抢口罩,有6箱口罩,第一箱占空间2,里面的口罩价值2k元,第二箱空间为2,价值3k元,3.3空间1k,4.1空间价值5k,5.5空间4k,6.2空间2k。

这是一个典型的01背包问题(改一改就是多重背包了),01背包说白了就是个选与不选的问题。在第x个物品时,我们只需知道不选x产品(x-1)个物品该空间(v)的下最大收益情况和选x产品时的最大收益情况(也就是x的收益加上x-1物品时n-v(x)收益的情况),取其较大者即可。

更具体点说只有一个物品时无论你有多少空间,价值只能是该物品的价值或者0,再多一个时,就考虑选了能否装下上一个物品,若可以则装下,若不可以则其大者而存之,三个的情况下则从第二个的状态中,找每次都是最优的状态。

有一个细节就是谁是外层循环,如果是01背包问题就是物品作为外层循环,因为得保证物品只被选中一次,如果完全背包(物品无限多,只价值最大)问题就是空间作为外层循环,总之谁只能用一次,谁就该在外层(01背包商品(或者转换的多重背包)只能取一次,商品可以重复使用)。有空了总结下各种背包问题好了

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        int n = new Scanner(System.in).nextInt();
        int[][] k = new int[][]{{2, 2}, {3, 2}, {1, 3}, {5, 1}, {4, 5}, {3, 2}};
        int[][] dp = new int[2][k.length+1];
        for (int i = 0; i < k.length; i++) {
            int this_inx,pre_inx;
            if((i&1)==1){
                this_inx = 1;
                pre_inx = 0;
            }else {
                this_inx = 0;
                pre_inx = 1;
            }
            for (int j = 1; j < n+1; j++) {
                if(j>=k[i][1]) {
                    dp[this_inx][j] = Math.max(dp[pre_inx][j], dp[pre_inx][j - k[i][1]] + k[i][0]);
                }
            }
        }
        System.out.println((n&1)==1?dp[1][n]:dp[0][n]);
    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值