トピック
説明
n個のアイテムからいくつかのアイテムを選び、バックパックに入れます。最大でいくらまで満たすことができますか?バックパックのサイズがmで、各アイテムのサイズがA_ {i} Ai
であるとします。
(各項目は1回のみ選択できます)
サンプル
例1:
入力:
配列=[3,4,8,5]
バックパックサイズ=10
出力:
9
説明:
4と5をロードします。
例2:
入力:
配列=[2,3,5,7]
バックパックサイズ=12
出力:
12
説明:
5と7をロードします。
分析する
アイテムを分割することはできません。各アイテムには、従来の01ナップサック問題、直接2次元状態配列、行は耐荷重、列はアイテム数、値はブール型、および値1は、最初のi個のアイテムを組み合わせて重みjにすることができることを意味します。
1.最後のステップ
現在のアイテムを服用するかどうかで、現在のバックパックの耐荷重を補うことができます。現在のアイテムはn番目のアイテムです。服用しない場合は、最初のn-1アイテムが耐荷重を補うことができるかどうかを確認してください。 。それを取るとき、最初のn-1アイテムを見てください。各アイテムは、現在のバックパックの重量から現在のアイテムの重量を引いたものになりますか?
2.伝達方程式
f [i] [j] = {f [i] [j-1] || f[i-現在のアイテムの重量][j-1]}(i> =現在のアイテムの重量)
コードセクション
1.初期化
f [0] [j]=trueアイテムを受け取らないときは耐荷重能力0を満たします
f[i][0]=falseアイテムを受け取らないときは0より大きい重量を見つけてはなりません
int len=A.size();
//承重 第几个物品
vector<vector<bool> > f(m+1,vector<bool>(len+1,false)); //状态
f[0][0]=true;
for(int i=1;i<=m;i++) //初始化
f[i][0]=false;
for(int i=1;i<=len;i++)
f[0][i]=true;
2.ダイナミックゲージコア
int ans=0;
for(int i=1;i<=m;i++) //动规核心
{
for(int j=1;j<=len;j++)
{
f[i][j]=f[i][j-1];
if(i>=A[j-1])
{
f[i][j]=f[i][j]||f[i-A[j-1]][j-1];
}
if(f[i][j])
ans=i;
}
}
完全なコード
class Solution {
public:
int backPack(int m, vector<int> &A) {
int len=A.size();
//承重 第几个物品
vector<vector<bool> > f(m+1,vector<bool>(len+1,false)); //状态
f[0][0]=true;
for(int i=1;i<=m;i++) //初始化
f[i][0]=false;
for(int i=1;i<=len;i++)
f[0][i]=true;
int ans=0;
for(int i=1;i<=m;i++) //动规核心
{
for(int j=1;j<=len;j++)
{
f[i][j]=f[i][j-1];
if(i>=A[j-1])
{
f[i][j]=f[i][j]||f[i-A[j-1]][j-1];
}
if(f[i][j])
ans=i;
}
}
return ans;
}
};
要約する
バックパック問題、耐荷重を状態に置き換える必要があります、01バックパック問題、別の次元はアイテムの数を表し、完全なバックパックの場合、他の次元は取るアイテムの数を表します。完全なバックパックには多くのアイテムがあるためです。 。同じ項目
、このメソッドは微妙であり、acメソッドは後で更新されます