zoukankan      html  css  js  c++  java
  • 记录一道面试题

    题目

    有一个背包,体积是v,有一些物品,占用的体积是w,每个物品可以无限拿,问多少种办法可以把背包恰好状态。

    解题

    设:dp[i][v] = dp[i-1][v] + dp[i][v-w[i]]
    前i个物品,恰好装满体积v的方法有俩个来源。前i-1个物品恰好装满v和 前i个物品恰好装满 v-w[i]
    dp[i][v-w[i]] 可能不好理解,举个例子,当前体积是5,第二个物品占用的体积是2,装第二个物品时,前俩个物品恰好装满体积3时,在放入一个第二个物品也是可以装满体积5的。
    代码如下:
    需要先枚举体积:

    
    public class Main {
        static int[][] dp = new int[5000][5000];
    
        public static void main(String[] args) throws Exception {
            //int[] num = {0, 1, 2, 3, 4, 5};
            int[] num = {0,  2, 3, 4, 5};
            int total = 5;
            init();
    
            for (int v = 1; v <= total; ++v) {
                for (int i = 1; i < num.length; ++i) {
                    if (v < num[i]) {
                        dp[i][v] = dp[i - 1][v];
                        continue;
                    }
                    dp[i][v] = dp[i - 1][v] + dp[i][v - num[i]];
                }
            }
            System.out.println(dp[num.length - 1][total]);
        }
    
        private static void init() {
            for (int i = 0; i < 5000; i++) {
                dp[i][0] = 1;
            }
        }
    }
    

    dp数组二维降成一维

    dp[v] = dp[v] + dp[v-num[i]]
    当前v的体积,可以放满的方法数=当前已经放满的方法数 + v-num[i]的方法数。
    需要先枚举物品,再枚举体积,要不然会出现状态被覆盖。

    /**
     * Created by Yanwu 2018/2/8.
     */
    public class Main {
    
        //static int[] dp2 = new int[5000];
        static int[] num = {0, 1, 2, 4};
        static int total = 5;
        static int[] dp2 = new int[total + 1];
        static int[][] dp = new int[total + 1][total + 1];
    
        public static void main(String[] args) throws Exception {
            //int[] num = {0, 1, 2, 3, 4, 5};
            dp1();
            dp2();
        }
    
        private static void dp1() {
    
            init();
            for (int v = 1; v <= total; ++v) {
                for (int i = 1; i < num.length; ++i) {
                    if (v < num[i]) {
                        dp[i][v] = dp[i - 1][v];
                        continue;
                    }
                    dp[i][v] = dp[i - 1][v] + dp[i][v - num[i]];
                }
            }
            System.out.println(dp[num.length - 1][total]);
        }
    
        private static void dp2() {
            dp2init();
    
            int total = 5;
    
            for (int i = 1; i < num.length; ++i) {
                for (int v = 1; v <= total; ++v) {
                    if (v - num[i] >= 0) {
                        dp2[v] = dp2[v] + dp2[v - num[i]];
                    }
    
                }
            }
            System.out.println(dp2[total]);
        }
    
        private static void dp2init() {
            for (int i = 0; i < dp2.length; ++i) {
                dp2[i] = 0;
            }
            dp2[0] = 1;
    
        }
    
        private static void init() {
            for (int i = 0; i <= total; i++) {
                dp[i][0] = 1;
            }
        }
    }
    
  • 相关阅读:
    openstack nova 基础知识——Quota(配额管理)
    02python注释
    01使用Pycharm编写第一个python程序
    35Angular实现一个todoList
    34Angular实现搜索缓存数据功能
    33Angular实现人员登记系统(表单元件的双向数据绑定)
    32练习
    31封装一个网络请求的服务
    30服务(练习)
    29服务
  • 原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/14249654.html
Copyright © 2011-2022 走看看