背包问题——以leetcode322、面试题 08.11. 硬币等为例

背包问题

陆续做到了几道背包的题,先开个坑吧。

1.著名的背包九讲文字版
2.背包九讲b站视频

01背包,即每种物品都只有1个,只有选和不选两种情况
完全背包,每种物品的个数都是无限的

LeetCode 322 零钱兑换

背包问题——以leetcode322、面试题 08.11. 硬币等为例_第1张图片
题目链接

这道题求的是所需最少硬币数

class Solution {
    public int coinChange(int[] coins, int amount) {
        int max = amount + 1;
        //dp:最少硬币个数
        //i:总金额
        int[] dp = new int[amount + 1];
        Arrays.fill(dp, max);
        dp[0] = 0;
        for (int i = 1; i <= amount; i++) {
            // for (int j = 0; j < coins.length; j++) {
            //     if (coins[j] <= i) {
            //         dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
            //     }
            // }
            for (int coin : coins) {
                if (coin <= i) {
                    dp[i] = Math.min(dp[i], dp[i - coin] + 1);
                }
            }
        }
        return dp[amount] > amount ? -1 : dp[amount];
    }
}

面试题 08.11. 硬币

背包问题——以leetcode322、面试题 08.11. 硬币等为例_第2张图片
题目链接

这道题求的是总情况数,所以是一个累加的过程

class Solution {
    public int waysToChange(int n) {
        //这里的coins数组题目没有将它作为输入值,所以要自己写出,顺序无所谓
        int[] coins = {25, 10, 5, 1};

        int[] dp = new int[n + 1];
        //dp[0]的意义是,正好可以用一个硬币代替的那一种情况
        dp[0] = 1;

        for (int coin : coins) {
            for (int i = coin; i <= n; i++) {
                //注意题目已说明结果可能会很大,你需要将结果模上1000000007
                dp[i] = (dp[i] + dp[i - coin]) % 1000000007;
            }
        }

        return dp[n];
    }
}

01背包问题

出处

/**
 * @Author: Aries
 * @Description: 背包问题
 * @Date: Create in 16:44 2020/2/29
 */
public class KnapSackProblem {
    public static void main(String[] args) {
        //物品重量
        int[] w = {1, 4, 3};
        //物品价值
        int[] val = {1500, 3000, 2000};
        //背包容量
        int m = 4;

        int n = val.length;
        //二维数组。表示 在考虑了前i个物品的情况下 容量为j的背包 能够装入的最大价值
        int[][] v = new int[n + 1][m + 1];

        //初始化。要初始化第一行和第一列。(也可以不设置,默认为0)
        // 第一列
        for (int i = 0; i < v.length; i++) {
            v[i][0] = 0;
        }
        // 第一行
        for (int i = 0; i < v[0].length; i++) {
            v[0][i] = 0;
        }

        //动态规划
        for (int i = 1; i < v.length; i++) {
            for (int j = 1; j < v[i].length; j++) {
                if (w[i - 1] > j) {
                    v[i][j] = v[i - 1][j];
                } else {
                    v[i][j] = Math.max(v[i - 1][j], val[i - 1] + v[i - 1][j - w[i - 1]]);
                }
            }
        }

        //输出
        for (int i = 0; i < v.length; i++) {
            for (int j = 0; j < v[i].length; j++) {
                System.out.print(v[i][j] + " ");
            }
            System.out.println();
        }
    }
}

你可能感兴趣的:(LeetCode超神之路)