背包问题标准模板

本文提供01背包、完全背包及多重背包的C++与Java实现模板,通过实例演示如何求解最大价值。

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

背包问题很多都可以转化为基本的01背包或者完全背包来解决,所以在弄懂之后写一套背包问题的模板备用也是十分有必要的~这是我写的模板,当遇到具体问题还需要具体对待,比如果什么是“价值”什么是“重量”什么是“容量”,不同问题不一样的,有些问题还需要做出不少改动,相信如果你弄懂背包问题的话这些都不是什么问题,废话不多说,上代码。

/*
	01背包,完全背包,多重背包模板 C++
	作者:桐小目
	时间:2016/01/28
*/
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=100005;
int dp[maxn];
int volume;
void ZeroOneBag(int value,int weight){                         //01背包
	for(int i=volume;i>=weight;i--)
		dp[i]=max(dp[i],dp[i-weight]+value);
}
void CompleteBag(int value,int weight){                        //完全背包
	for(int i=weight;i<=volume;i++)
		dp[i]=max(dp[i],dp[i-weight]+value);
}
void MultipleBag(int value,int weight,int number){             //多重背包(二进制优化)
	if(number*weight>=volume) {  //如果满足此条件可视为完全背包问题解决
		CompleteBag(value,weight);
		return;
	}
	int i=1;
	while(i<=number){            //二进制优化
		ZeroOneBag(i*value,i*weight);
		number-=i;
		i<<=1;
	}
	ZeroOneBag(number*value,number*weight);
}
int main(){                                                  //以下皆为测试,经测试没有出现错误
	int k=0;
	while(true){
	cout<<"--------------------------"<<endl;
	cout<<"输入0,01背包"<<endl<<"输入1,完全背包"<<endl<<"输入2,多重背包"<<endl<<"输入3,结束"<<endl;
	cout<<"--------------------------"<<endl;
	cin>>k;
	if(k==3) break;
	int n,value[maxn],weight[maxn],number[maxn];
	memset(dp,0,sizeof(dp));
	switch(k){
	case 0:
		cout<<"输入物品个数和背包容量"<<endl;
		cin>>n>>volume;
		cout<<"输入物品价值"<<endl;
		for(int i=1;i<=n;i++) 
			cin>>value[i];
		cout<<"输入物品重量"<<endl;
		for(int i=1;i<=n;i++) 
			cin>>weight[i];

		for(int i=1;i<=n;i++)
			ZeroOneBag(value[i],weight[i]);
		cout<<"结果为: "<<dp[volume]<<endl;
	break;
	case 1:
		cout<<"输入物品个数和背包容量"<<endl;
		cin>>n>>volume;
		cout<<"输入物品价值"<<endl;
		for(int i=1;i<=n;i++) 
			cin>>value[i];
		cout<<"输入物品重量"<<endl;
		for(int i=1;i<=n;i++) 
			cin>>weight[i];

		for(int i=1;i<=n;i++)
			CompleteBag(value[i],weight[i]);
		cout<<"结果为: "<<dp[volume]<<endl;
	break;
	case 2:
		cout<<"输入物品种类数和背包容量"<<endl;
		cin>>n>>volume;
		cout<<"输入物品价值"<<endl;
		for(int i=1;i<=n;i++) 
			cin>>value[i];
		cout<<"输入物品重量"<<endl;
		for(int i=1;i<=n;i++) 
			cin>>weight[i];
		cout<<"输入物品个数"<<endl;
		for(int i=1;i<=n;i++) 
			cin>>number[i];

		for(int i=1;i<=n;i++)
			MultipleBag(value[i],weight[i],number[i]);
		cout<<"结果为: "<<dp[volume]<<endl;
	break;
		}
	}
}

以上是C++代码,顺便也准备了一份Java的代码,基本一样,也贴上来

/*
 * 01背包,完全背包,多重背包标准模板
 * Author:桐小目
 * Language:Java
 * date:2016/01/28
 */
import java.util.*;
public class DEMO {
	public static int dp[]=new int[100005],volume;
	public static void ZeroOneBag(int value,int weight){                         //01背包
		for(int i=volume;i>=weight;i--)
			dp[i]=Math.max(dp[i],dp[i-weight]+value);
	}
	public static void CompleteBag(int value,int weight){                        //完全背包
		for(int i=weight;i<=volume;i++)
			dp[i]=Math.max(dp[i],dp[i-weight]+value);
	}
	public static void MultipleBag(int value,int weight,int number){             //多重背包(二进制优化)
		if(number*weight>=volume) {  //如果满足此条件可视为完全背包问题解决
			CompleteBag(value,weight);
			return;
		}
		int i=1;
		while(i<=number){            //二进制优化
			ZeroOneBag(i*value,i*weight);
			number-=i;
			i<<=1;
		}
		ZeroOneBag(number*value,number*weight);
	}
	public static void main(String[] args){
		Scanner input=new Scanner(System.in);                                   //测试略
	}
}


继续加油~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值