背包模板(01,完全,多重背包的二进制优化和单调队列优化

本文探讨了背包问题的三种类型:01背包、完全背包和多重背包,并介绍了针对多重背包的二进制优化方法,通过构建特定数列减少计算复杂度。同时,还介绍了利用单调队列进行的优化,通过两个队列提高求解效率,参考了相关博客和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背包问题

1,01背包

背包问题的基础,总体积为V的背包,有n件体积v【i】,价值w【i】的物品,求能装物品的最大总价值

 

void zero(int v,int w)
{
	for(int j=V;j>=v;j--)
	{
		dp[j]=max(dp[j],dp[j-v]+w);
	}
	return ;
}

 

 

 


2.完全背包,每件物品能选无数个

 

 

 

void complete(int v,int w)
{
	for(int j=v;j<=V;j++)
	{
		dp[j]=max(dp[j],dp[j-v]+w);
	}
	return ;
} 

3.多重背包,每件物品能选的数量有限制,最多c【i】个

 

二进制优化:

二进制优化的思想还是很巧妙的,根据c【i】得到一组这样的数 2^0,2^1,2^2,2^3.....2^(k-1) , c-2^k+1  其中k是满足2^k小于c的最大值,就像c=7=111,2^k=100=4  ;

 c=9=1001, 2^k=1000=8  ;  c=8=1000  2^k=0100=4   

得到这组数的目的是什么呢,

很抱歉,由于我是一名语言模型AI,我并不具备直接运行代码的能力。但是,我可以为您提供一些关于多重背包二进制优化输入c代码的信息建议。 多重背包问题是一种经典的动态规划问题,二进制优化是对传统多重背包算法的一种优化手段,可以大幅提升算法性能。 以下是一个可能的多重背包二进制优化输入c代码的基本框架: ```c #include <stdio.h> #define MAXN 1005 int N; // 物品数量 int W; // 背包总容量 int w[MAXN]; // 每个物品的重量 int v[MAXN]; // 每个物品的价值 int f[MAXN][MAXN]; int max(int a, int b) { return a > b ? a : b; } int main() { scanf("%d %d", &N, &W); for (int i = 1; i <= N; i++) { scanf("%d %d", &w[i], &v[i]); } // 以下为二进制优化部分 int n = 1; for (int i = 1; i <= N; i++) { int k = 1; while (k <= v[i]) { w[n] = k * w[i]; v[n++] = k * v[i]; v[i] -= k; k *= 2; } if (v[i] > 0) { w[n] = v[i] * w[i]; v[n++] = v[i] * v[i]; } } N = n - 1; // 多重背包部分 for (int i = 1; i <= N; i++) { for (int j = W; j >= w[i]; j--) { for (int k = 1; k * w[i] <= j; k++) { f[j] = max(f[j], f[j - k * w[i]] + k * v[i]); } } } printf("%d\n", f[W]); return 0; } ``` 以上代码实现了基于二进制优化多重背包问题,通过对每个物品按其价值进行二进制拆分,并将其转化为多个物品,以便于后续的多重背包求解。 需要注意的是,该算法的时间复杂度为 $O(NV\log V)$,其中 $V$ 为所有物品的总价值。如果您需要更高效的算法实现,可以尝试其他优化技巧,如单调队列优化、有界背包优化等。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值