01ナップサック問題、完全なナップサック問題(再帰的解決)

01バックパックのi番目のアイテムを選択するときに、ボリュームが十分である場合、選択できる状態は2つだけで、置くかどうかにかかわらず、最も価値のあるオプションを見つけます

完全なバックパックがi番目のアイテムを選択するとき、ボリュームが十分である場合、1つ、または2つ、3つ、またはそうでない、3つ以上の状態から選択できます。最も価値のあるオプションを見つける

01ナップサック問題

 

入力:

5 8 // 5つのアイテムのバックパックの容量は8です

4 5 2 1 3 //アイテム値

3 5 1 2 2 //アイテム数量

出力:

10 //最大値

#include<iostream>
using namespace std;
int w[100];
int v[100];
int maxValue;
int n,weight;    
void dfs(int sum,int nowWeight,int step)
{
	if(nowWeight>weight) //超出重量 则回退 
	return ;
	if(step==n) { //已经完成n件物品的选择 
		if(sum>maxValue)	
		maxValue=sum;	// 更新最大价值 
		return ;
	}
	dfs(sum+v[step],nowWeight+w[step],step+1);  //选这件物品
	dfs(sum,nowWeight,step+1);					//不选这件物品 
}

int main(void)
{
	cin>>n;
	cin>>weight;
	for(int i=0;i<n;i++)
		cin>>v[i];
	for(int i=0;i<n;i++)
		cin>>w[i];
	 
	dfs(0,0,0);
	cout<<maxValue<<endl;
	return 0;
}

完全なナップザック問題

例:いくつかのギフトがあり、各ギフトにはその価値と重量があり、それらからギフトを選択し、選択したギフトの合計重量がw以下で、合計値が最大になるように重量値wを指定します。

        入力:1行目はギフトの数、2行目は各ギフトの値、3行目は各ギフトの重量、4行目は指定された重量値です。

        出力:最大値

        例:5

                   5000 4000 3000500200

                   5 4 6 3 1

                  10

        出力:9200


 

#include<iostream>
using namespace std;
int w[100];
int v[100];
int maxValue,n,weight;    
void dfs(int sum,int nowWeight,int step)
{
	if(nowWeight>weight||step>=n)		//当前重量大于最大重量 或全部选完 
	return ;		//回退 
	if(sum>maxValue)
	maxValue=sum;
	dfs(sum+v[step],nowWeight+w[step],step+1);  //选这件物品 然后选下一件 
	dfs(sum+v[step],nowWeight+w[step],step); 	//选这件物品 然后继续选这一件 
	dfs(sum,nowWeight,step+1);					//不选这件物品 
}

int main(void)
{
	cin>>n;
	for(int i=0;i<n;i++)
		cin>>v[i];
	for(int i=0;i<n;i++)
		cin>>w[i];
	cin>>weight;
	dfs(0,0,0);
	cout<<maxValue<<endl;
	return 0;
}

 

上記のコードの本質は、ブルートフォース解決を実行し、各状況の値を列挙してから適切な削減を実行することです。もちろん、動的計画法の方が優れた方法です。

おすすめ

転載: blog.csdn.net/a447332241/article/details/87977231