混合背包详解


前置知识

0-1背包:对于每种物品,最多只能选取1次,每种物品存在选与不选

完全背包:对于每种物品,可以无限多次获取

多重背包:对于每种物品,最大获取次数有限,通常可以使用二进制优化并结合0-1背包公式解决问题


一、混合背包的概念

简单来说就是多重背包与完全背包的混合,也就是说既存在可以无限获取的物品,也存在获取上限的物品

二、习题演示

1.洛谷P1833樱花

在这里插入图片描述

1.解题思路与代码

通常的思路就是if判断,由于0-1背包可以看成是只有1次的多重背包,所以if两重判断就可以完成对完全背包和多重背包的分离处理

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N = 1e4+5;

int h1,h2,m1,m2,n;
char d1;

int w[N], v[N], p[N];
int dp[1001];

int main(){
	cin >> h1 >> d1 >> m1 >> h2 >> d1 >> m2 >> n;
	int d = (h2-h1)*60+m2-m1;
	for(int i=1; i<=n; ++i){
		cin >> w[i] >> v[i] >> p[i];
	}
	for(int i=1; i<=n; ++i){
		if(p[i] == 0){	//完全背包
			for(int j=w[i]; j<=d; ++j){
				dp[j] = max(dp[j], dp[j-w[i]]+v[i]);
			}
		}
		else{			//多重背包
			//二进制优化
			for(auto l=1; l<=p[i]; l<<=1){
				for(int j=d; j>=l*w[i]; --j){
					dp[j] = max(dp[j], dp[j-l*w[i]] + l*v[i]);
				}
				p[i] -= l;
			}
			if(p[i] == 0)	continue;
			for(int j=d; j>=p[i]*w[i]; --j){
				dp[j] = max(dp[j], dp[j-p[i]*w[i]]+p[i]*v[i]);
			}
		}
	}
	cout << dp[d];
	return 0;
}

总结

1.混合背包没有什么难的点,实际只要会完全背包和多重背包,混合背包也无非就是多加一点判断的事

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值