笔试题目记录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]);
    }

}

发布了18 篇原创文章 · 获赞 1 · 访问量 255

猜你喜欢

转载自blog.csdn.net/qq_38732834/article/details/105524030