背包问题标准模板

背包问题很多都可以转化为基本的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);                                   //测试略
	}
}


继续加油~

背包问题是一类组合优化的问题。在最简单的形式中,它可以被描述为:给定一组物品,每种物品都有自己的重量和价值,在限定的总重量内,我们应该如何选择装入背包的物品,使得背包中的物品总价值最大。背包问题有许多变种,如0-1背包问题、分数背包问题、多重背包问题等。 针对不同类型和复杂度的背包问题,开发环境的选择可能会有所不同,但通常会依赖于以下几个关键要素: 1. 编程语言:C++、Java和Python等编程语言因其丰富的库支持和良好的性能被广泛用于解决背包问题。C++通常用于追求性能极致的场合,而Python因其简洁和快速原型设计而受欢迎。 2. 开发工具:集成开发环境(IDE)如Visual Studio、Eclipse、IntelliJ IDEA或简洁的文本编辑器如Visual Studio Code、Sublime Text都可以用来编写和调试解决背包问题的代码。 3. 图形化工具:对于背包问题的演示和教学,可能会用到图形化工具来展示背包填充的过程和结果。如使用Matplotlib库在Python中绘制背包填充的动态图解。 4. 算法库:一些算法库可能提供了现成的背包问题求解函数或算法框架,例如在C++中有Knuth-Morris-Pratt库或C++标准模板库(STL),在Python中有NumPy库进行数值计算等。 5. 性能测试:在解决背包问题时,可能会使用性能测试工具如JUnit、Python的unittest框架,来确保算法在不同情况下都能保持良好的性能。 开发环境的具体选择取决于项目的需求、开发者的熟悉程度以及性能要求等因素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值