バックパック学習ノート

序文:バックパックは無数に学ばれてきたが、今回はようやくQAQを覚えている

----------------

バックパックは線形DPの重要で特別なモデルです。

0/1バックパック

$ n $アイテムが与えられた場合、$ i $アイテムのボリュームは$ w_ {i} $で、値は$ c_ {i} $です。ボリューム$ m $のバックパックを手に入れましょう。アイテムの合計値を最大化する方法は?

最初にナイーブアルゴリズムを検討します。

$ f [i] [j] $を、最初の$ i $アイテムを考慮し、合計量$ j $のアイテムを選択してバックパックに入れることによって取得される最大値とします。

$ i $アイテムを選択しない場合、$ f [i] [j] = f [i-1] [j] $となります。

$ i $アイテムを選択すると、$ f [i] [j] = f [i-1] [j-w_ {i}] + c_ {i}(j \ geq w_ {i})$になります。2つの最大値を取ります。

最適化を検討してください。$ i $アイテムを検討する場合、それは$ i-1 $アイテムを検討する場合の状況にのみ依存するため、上記の$ f $配列の最初の次元は省略できます。

即$ f [j] = max(f [j]、f [jw [i]] + c [i])$。

注意:$ j $は逆の順序でループします。正のシーケンスループを想定します。たとえば、$ jw {i} $を$ j-2w_ {i} $の状況で更新するには、この時点で$ jw {i} $は$ i $番目のステージに移行し、$ jw {にリサイクルされます。 i} $の場合、「$ i $ thステージが$ i $ thステージを更新する」という状況が発生し、線形DPの原則に違反します。逆順サイクルにより、線形DPの原則に沿って、各アイテムが1回だけ検討されることが保証されます。

-------------------------------

完全なバックパック

条件が追加されていることを除けば、0/1バックパックに似ています。各アイテムを何度も選択できます。

 

0/1バックパックとの唯一の違い:$ j $は正のシーケンスサイクルです。各アイテムを無数に選択できるため。

$ f [j] = max(f [j]、f [j-w_ {i}] + c_ {i} $。

-------------------------------------

複数のバックパック

条件はフルバックパックとは異なります:各アイテムは$ t_ {i} $回選択できます。

最も単純な方法は、もちろん$ 0 $から$ t_ {i} $までループして、それぞれの場合に再試行することです。しかし、複雑さはさらに高くなります。

バイナリ分割法を使用できますご存じのとおり、$ 2 ^ 0,2 ^ 1,2 ^ 2、...、2 ^ k-1 $は、$ 0 $から$ 2 ^ k -1 $までのすべての整数を表すことができます。したがって、このメソッドを使用して、アイテムをバイナリに分割できます。$ r_ {i} = c_ {i} -2 ^ 0-2 ^ 1 -...- 2 ^ p $の場合、$ p + 2 $アイテムに分割でき、ボリュームは$ 2 ^ 0 * w_ {i}、2 ^ 1 * w_ {i}、...、2 ^ p * w_ {i}、r_ {i} * w_ {i} $。このメソッドは、アイテムを$ logc_ {i} $に分割します。これはより効率的です。

------------------

グループバックパック

条件の変更:$ i $個のアイテムグループがあり、各アイテムグループには$ k $個のアイテムがあり、各グループは最大値に対して最大1つのアイテムを選択できます。

$ k $サイクル選択を直接行います。選択が完了している限り、すぐに$ i $ステージから$ i + 1 $状態に遷移します。

forint i = 1 ; i <= n; i ++ forint j = m; j> = 0 ; j -- forint k = 1 ; k <= c [i]; k ++ if(j > = v [i] [k])f [j] = max(f [j]、f [iv [i] [k])+ w [i] [k]

 

$ k $サイクルは$ j $サイクル内にある必要があることに注意してください。

おすすめ

転載: www.cnblogs.com/Invictus-Ocean/p/12694265.html