139、单词拆分
dp[i]:长度为 i 的字符串可以有字典中出现的单词拼接出来。
if s[j: i] in wordDict and dp[j] == true
则 dp[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]);
}
}