01背包 递归 dp

8 篇文章 0 订阅
4 篇文章 0 订阅
import java.util.Arrays;
import java.util.Scanner;

public class _01Inventory {
    static int n;
    static int w;
    static int[] weight;
    static int[] value;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        n = scanner.nextInt();
        w = scanner.nextInt();
        weight = new int[n];
        value = new int[n];
        for (int i = 0; i < n; i++) {
            weight[i] = scanner.nextInt();
        }
        for (int i = 0; i < n; i++) {
            value[i] = scanner.nextInt();
        }
        System.out.println(dfs(0, w));
        dp = new int[n + 1][w + 1];
        System.out.println(memoRecursion(0, w));
        dp();
    }

    // 第几个物品 剩余重量
    public static int dfs(int k, int n) {
        if (k == _01Inventory.n) return 0;
        if (n <= 0) return 0;
        int r1 = dfs(k + 1, n);
        if (weight[k] <= n) {
            int r2 = value[k] + dfs(k + 1, n - weight[k]);
            return Math.max(r1, r2);
        } else {
            return r1;
        }
    }

    static int[][] dp;

    // 用excel分析 记忆性递归(也是dp的一种 俗称自顶向下)
    public static int memoRecursion(int k, int ww) {
        if (k == n) return 0;
        if (ww <= 0) return 0;
        if (dp[k][ww] != 0) { // 如果没有重量为0的物品 这样就没什么问题 因为没有容量不能产生价值
            return dp[k][ww]; // 计算之前做查询,计算之后做保存
        }
        int ans1 = memoRecursion(k + 1, ww);
        if (ww >= weight[k]) {
            ans1 = Math.max(ans1, value[k] + memoRecursion(k + 1, ww - weight[k]));
        }
        dp[k][ww] = ans1;
        return ans1;
    }

    public static void dp() { // n 物品数 w重量
        int[][] dp = new int[n][w + 1];
        /*for (int i = 0; i < n;i++){
            dp[i][0] = 0;
        }*/
        for (int j = 1; j < w + 1; j++) {
            if (weight[0] <= j) {
                dp[0][j] = value[0];
            }
        }
        for (int i = 1; i < n; i++) {
            for (int j = 1; j < w + 1; j++) {
                if (weight[i] <= j) {
                    dp[i][j] = Math.max(dp[i - 1][j], value[i] + dp[i - 1][j - weight[i]]);
                } else {
                    dp[i][j] = dp[i - 1][j];
                }
            }
        }
        for (int[] s : dp) {
            System.out.println(Arrays.toString(s));
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值