事前最初のブログであなたを感謝
タイトルリンクします。https://www.luogu.org/problemnew/show/P2871
タイトル説明
N項目Vとバックパックの容量があります。重みは、i番目の項目Cである[I]、W [I]の値です。これらの項目の重みの和がバックパックの容量、および最大値の合計を超えないことができ、バックパックの中に物品を解きます。
入力フォーマット:
最初のライン:N項目の数とMサイズのバックパック
第二行第2列N + 1:重量C [i]とW [i]が値であることにより、i番目の記事
:出力形式
、出力ラインの最大値。
例:
入力:
4 6
1 4
2 6
3 12
2 7
出力:
23回
の分析これは、標準的な動的計画問題--01バックパックです。
最初の記事で01バックパック01は、物品の2つのだけの状態を意味する-選択された選択はなく
、我々は、2次元アレイFを設定することができる[M] [N]を、
nはMの関係を説明すると、Mから選択される配列を意味しますM員、NはバックパックがNである場合、最大容量を意味し;そして
wは、[I](等占める位置/費用)の項目のi番目の重みを表し、cはタイトルの私達の意味で2次元アレイが設けられています[ i]が得られた項目の後にこれを選択した値(リターン/スコア、等)を指します。
だから我々は唯一つの項目を選択してプッシュDP方程式の2種類で選択されていませんがあります。
この項目は、以下から選択されたときに
明らかF [M] [N-] = F [M-1] [NC [m]は] + W [M]
(もちろん、この記事では、背後にあるコードを参照するのに十分なスペースが必要)
説明:
に選出M-作品、それがこのために選挙の前に約これの最大にあなたがwの値を追加することを確認されたm個をプッシュするために選択したNC [M]からの最初のm個のアイテムをしなければならない拘束[M]
ときに、この項目が選択されていない
F [m]を見[N] = F [M-1] [n]の
説明:
同様に第1、M-1 Mのメンバーからこの記事の前に選出されなければなりませんそのように、nの体積と考えることができないではないので、それが選択されていないプッシュする
上記の二つのケースによって、我々は、F [m]を定義するために[n]は、F、次に最大であるべきである[m]は[n]は、上記の場合のものであるべきです最大
即ちDP式:F [M] [N-] = MAX(F部[NC [M] + W [M]、F [1-M] [N-] [1-M。]。)
であれば、最後のトラックのように出力F [アイテムの合計数]言って[総容量]言うまでもなく
のコードを:
書式#include <iostreamの> の#include <cstdioを> 使用して 名前空間はstdを、 長い 長い F [ 10000 ] [ 10000 ]、C [ 100000 ]、W [ 100000 ]、S、V。 INT メイン() { CIN >> S >> V。 以下のための(長い 長 i = 1 ; iは= Sを<; iは++ ) CIN >> C [I] >> W [i]は、 以下のための(長い 長 M = 1、M <= Sであり; m ++ ) のための(長い 長 N = Vであり; n> 0; N--)// そのアイテムを保持することができる保証するために 、{ IF(N> = C [M])// 我々が保持できれば F [m]を[N-] = MAX(F [M- 1 ] [ N-]、F [M- 1 ] [NC [M] + W [M]); 他// それがグループから選択してはならない保持することはできません F [M] [N-] = F [M- 1 ] [N-]。 } COUT << F [S] [V]; 戻り 0 ; }
フォーカス:圧縮の状態を:
上記の説明のようにあるから、我々は理解することができます- F
[m]の[N-]どんなに選挙がバインドされているかF [M-1]は[nまたはNC [M]]に関連する値(フォーカスを描く)
こと、私たちがすることはできませんF [N] F圧縮状態アレイに[M] [n]の一次元、それ?
答えはイエスであり
、元の2次元DPに
、我々は値を変更するアレイの二重を使用し
、次いで編集されたF [N]の一部(すなわち、F [M] [N])のように二つの部分に分かれて配列が存在しなければならない
別の変更されていないため変形の最後の部分のために(すなわち、F [M-1] [nが ])
F [n]を変更しない限りの動員のための2つを達成することができる場合、我々は、修飾しましたDP次元圧縮
我々は元々 、二次元DPが考え
[M-1] fを動員F [M] [n]を変更[nまたはNC [M]容量(すなわち、それぞれのnに対応する)Fの比です[ M] [N]小さな
私たちは大きな優先穏やかな変更を再生できるという
Fを変更する]に変更されていません[N動員]は、その後、あなたはF [nまたはNC [メートルことを保証することができます]が
、理解するのがやや困難(自分自身の)主題についての詳細を考えるために組み合わせる
コードは一次元圧縮に置かれています
書式#include <iostreamの> の#include <cstdioを> 使用して 名前空間はstdを、 長い 長い F [ 1000000 ]、C [ 100000 ]、W [ 100000 ]、S、V。 INT メイン() { CIN >> S >> V。 以下のための(長い 長 i = 1 ; iは= Sを<; iは++ ) CIN >> C [I] >> W [i]は、 以下のための(長い 長 M = 1、M <= Sであり; m ++ ) のための(長い 長 N = V; N> 0 ; N--)//理解することが重要 { IF(N-> = C [M])// 我々が保持できる場合 F [N-] = MAX(F [N-]、F [NC [M] + ; W [m]は) 他に//がないし、し選択してはならない [N-] = F ; F [N-] } COUT << F [V]; 戻り 0 ; }
説明上の
支援のための最初のブログのおかげで