动态规划 | 139. 单词拆分、多重背包

139、单词拆分

动态规划 | 139. 单词拆分、多重背包_第1张图片

dp[i]:长度为 i 的字符串可以有字典中出现的单词拼接出来。

if s[j: i] in wordDict and dp[j] == truedp[i] = true

dp[0] = true, 因为后续均由dp[0]推出。

从前向后遍历

public static boolean wordBreak(String s, List<String> wordDict) {

    HashSet<String> wd = new HashSet<>(wordDict);

    boolean[] dp = new boolean[s.length()+1];
    dp[0] = true;

    for (int j = 1; j <= s.length(); j++) { // 背包
        for (int i = 0; i < j; i++){
            if (dp[i] && wd.contains(s.substring(i, j))) {
                dp[j] = true;
                break;
            }
        }
        System.out.println(Arrays.toString(dp));
    }
    return dp[s.length()];
}

多重背包

多重背包,即在物品重量和价值的两个维度上,又多了数量。

可以转化为01背包:数量为n的物品,代表n个数量为1的物品。
按照01背包的思路即可解题。

import java.util.ArrayList;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {

        Scanner in = new Scanner(System.in);

        int C = in.nextInt(); // 背包容量
        int N = in.nextInt(); // 物品种类

        ArrayList<Integer> weight = new ArrayList<>();
        ArrayList<Integer> value = new ArrayList<>();
        ArrayList<Integer> nums = new ArrayList<>();
        
        for (int i = 0; i < N; i++) weight.add(in.nextInt());
        for (int i = 0; i < N; i++) value.add(in.nextInt());
        for (int i = 0; i < N; i++) nums.add(in.nextInt());
        
        int[] dp = new int[C+1];

        for (int i = 0; i < weight.size(); i++) { // 物品
            for (int j = C; j >= weight.get(i); j--) {
                for (int k = 1; k <= nums.get(i) && (j - k * weight.get(i)) >= 0; k++) {
                    dp[j] = Math.max(dp[j], dp[j - k * weight.get(i)] + k * value.get(i));
                }
            }
        }

        System.out.println(dp[C]);
    }
}

你可能感兴趣的:(动态规划,算法)