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