混合背包问题

今天也是刚做了一下混合背包,原理很简单,就是把多重背包进行二进制优化转化为01背包,而01背包和完全背包不用变,最后判断是01背包还是完全背包进行遍历即可。

原题链接:7. 混合背包问题 - AcWing题库

 

 ac代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 5;
const int M = 1e6 + 5;
int n, m, cnt;
int dp[N];
int v[N], w[N], s[N];
int a[M], b[M], c[M];
int main()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> v[i] >> w[i] >> s[i];
	}
	for (int i = 1; i <= n; i++) {
		if (s[i] < 0) {//本身就是01背包,直接存起来
			cnt++;
			a[cnt] = v[i];
			b[cnt] = w[i];
			c[cnt] = 1;
		}
		else if (s[i] == 0) {//原来是完全背包,也是直接存起来
			cnt++;
			a[cnt] = v[i];
			b[cnt] = w[i];
			c[cnt] = 0;
		}
		else {//原来是多重背包,二进制优化,变成01背包后再存起来
			for (int j = 1; j <= s[i]; j *= 2) {
				s[i] -= j;
				cnt++;
				a[cnt] = v[i] * j;
				b[cnt] = w[i] * j;
				c[cnt] = 1;
			}
			if (s[i] > 0) {
				cnt++;
				a[cnt] = v[i] * s[i];
				b[cnt] = w[i] * s[i];
				c[cnt] = 1;
			}
		}
	}
	for (int i = 1; i <= cnt; i++) {
		if (c[i] == 1) {//01背包
			for (int j = m; j >= a[i]; j--) {
				dp[j] = max(dp[j], dp[j - a[i]] + b[i]);
			}
		}
		else if (c[i] == 0) {//安全背包
			for (int j = a[i]; j <= m; j++) {
				dp[j] = max(dp[j], dp[j - a[i]] + b[i]);
			}
		}
	}
	cout << dp[m] << endl;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值