第43天-DP-第九章 ● 139.单词拆分 ● 关于多重背包,你该了解这些! ● 背包问题总结篇!

1. 单词拆分

在这里插入图片描述s

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        unordered_set<string> wordSet(wordDict.begin(), wordDict.end());
        // 1. dp[i] 为true代表 可以拆分为一个或者多个在字典中出现的单词
        vector<bool> dp(s.size()+1, false);
        dp[0] = true;

        // 2.确定递推公式
        //   如果dp[j]是true并且, dp[j, i]在字典中出现过,那么一定为true
        //   所以公式应该为 if dp[j] && dp[j, i]在字典中出现过
        for(int i=1; i<=s.size(); i++){      // 先遍历背包ssssssssssssssssssssss
            for(int j=0; j<i; j++){
                string word = s.substr(j, i-j);
                if(dp[j] && wordSet.find(word) != wordSet.end()){
                    dp[i] = true;
                }
            }
        }


        return dp[s.size()];

        // 3.初始化数组    dp[i]全部初始化为false,  dp[0]初始化为true

        // 4.确定遍历顺序(组合是外层物品内层背包,排序是外层背包内层物品)
        //   本题applepenapple 必须由 apple pen apple 按顺序组合,因此本题属于排序问题

    }
};

2.多重背包

多重背包就是 可以重复使用物品,但是物品的数量是有限制的
因此可以将其转换为01 背包的问题,即将物品的数量展开
在这里插入图片描述

void mul_bag_proble() {

	vector<int> weight = { 1 , 3 , 4 };
	vector<int> value = { 15, 20, 30 };
	vector<int> nums = { 2 ,3, 2 };
	int bagweight = 10;

	for (int i = 0; i < nums.size(); i++) {
		while (nums[i] > 1) {
			weight.push_back(weight[i]);
			value.push_back(value[i]);
			nums[i]--;
		}
	}

	vector<int> dp(bagweight+1, 0);

	for (int i = 0; i < weight.size(); i++) {			// 先遍历物品
		for (int j = bagweight; j >= weight[i]; j--) {
			dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
		}

		for (int j = 0; j <= bagweight; j++) {
			cout << dp[j] << ", ";
		}
		cout << endl;
	}


	cout << dp[bagweight] << endl;
}

3. 背包总结

- 代码随想录链接

  • 背包的种类
    在这里插入图片描述
  • 背包的递推公式
    • 问背包是否能够装满 或者 最多可以装多少 max(dp[j], dp[j-i] + value[i])
    • 装满背包有多少种方法: dp[j] += dp[j-i]
    • 背包装满的最大价值: dp[j] = max(dp[j], dp[j-weight[i]]+value[i])
    • 装满背包的最小数: dp[j] = min(dp[j-coins[i] +1, dp[j])
  • 遍历顺序
    • 01背包
      • 二维dp数组:先遍历物品还是背包都可以,二层for循环是从小到大遍历
      • 一维dp数组:必须先遍历物品再遍历背包, 并且背包是从大到小的遍历
    • 完全背包
      • 求组合数: 外层for循环物品,内层循环背包容量
      • 求排序: 外层for循环背包, 内层for循环物品
      • 求最小数: 两个for循环顺序和大小都可以
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值