【动态规划】 加体积限制的01背包

本文介绍了二维0-1背包问题的解决方案,该问题在传统0-1背包基础上增加了体积限制。算法通过动态规划求解物品的最大价值,并使用回溯法确定选择的物品。代码实现中,利用三维数组存储状态,复杂度为O(ncd)。最终展示最大价值及所选物品。

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

2.0-1背包

在这里插入图片描述

算法思路:

此题在最基础的0-1背包问题上加了一个体积限制,其基本思想不变。

记录容量为1—c,容积为1—d的背包处理前i的物品的最大价值

考虑能不能装下第i个物品,装得的话考虑值不值得装

用一个回溯来记录选择了哪些物品

代码实现:

#include<bits/stdc++.h>
using namespace std;
#define N 100
#define V 100
#define W 100
int n,c,d;
int w[N],b[N],v[N];
int dp[N][W][V];  //dp[i][j][k]表示用容量为j, 容积为k的背包来处理前i个物品 
int select[N];

void findAns(int n1,int c1,int d1){
	if(n1>0){
		if(dp[n1][c1][d1] == dp[n1-1][c1][d1]){
			select[n1] = 0;
			findAns(n1-1,c1,d1);
		} 
		else if(c1 >= w[n1] && d1 >= b[n1] &&  dp[n1][c1][d1] == dp[n1-1][c1-w[n1]][d1-b[n1]]+v[n1]){
			select[n1] = 1;
			findAns(n1-1,c1-w[n1],d1-b[n1]);
		}
	}
}

int main(){
	int n;
	scanf("%d%d%d",&n,&c,&d);
	for(int i=1;i<=n;i++) scanf("%d%d%d",&w[i],&b[i],&v[i]);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=c;j++){
			for(int k=1;k<=d;k++){
				if((j-w[i] >= 0) && (k-b[i] >= 0)){
					dp[i][j][k]=max(dp[i-1][j][k],dp[i-1][j-w[i]][k-b[i]]+v[i]);
				}
				else{
					dp[i][j][k]=dp[i-1][j][k];
				}
			}
		}
	}
	findAns(n,c,d);
	printf("最大价值为:%d\n",dp[n][c][d]);
	for(int m=1;m<=n;m++){
		//if(select[m]) printf("%d ",m);
		printf("%d ",select[m]);
	}
	return 0;
}

计算复杂性:O(ncd) 即O(n3)

测试:在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值