戦国IT - 情報処理技術者試験の過去問対策サイト
ブログお知らせお問い合わせ料金プラン

応用情報技術者 2017年 秋期 午後03


ナップザック問題に関する次の記述を読んで、設問1~3に答えよ。

  〔ナップザック問題〕  幾つかの種類の品物があり、それぞれの容積と価値が与えられているとき、選んだ品物の容積の合計が定められた値以下であるという条件(容量制限)を満たし、かつ、価値の合計(以下、価値合計という)が最大になるような品物の組合せを求める問題をナップザック問題という。  この問題では、一つの品物を選ぶ個数には制限がないものとする。例えば、容積、価値を表1に示した2種類の品物A、Bがあり、容量制限が5である問題を考える。この場合、品物Aを1個、品物Bを2個選ぶと、容積の合計は5、価値合計は14となり、選んだ品物の価値合計が最大となる。
応用情報技術者試験(平成29年度 秋期 午後 問03 表01)   〔動的計画法によるナップザック問題の解法〕  品物の容積や価値を正の整数に限定したナップザック問題に対して、動的計画法による解法が知られている。この問題に対する動的計画法は、元の容量制限以下の全ての値を容量制限としたときの、品物の種類を限定した問題(以下、小問題という)をあらかじめ解いておき、それらの解を用いることによって、元の問題の解を得る方法である。表2に示すような、選んだ品物の最大の価値合計を求める表に対して順に数値を埋めて考えると、この解法の手順は理解しやすい。
応用情報技術者試験(平成29年度 秋期 午後 問03 表02)    表2において、例えば、表1に示す品物A、Bを選べる場合の容量制限3までの小問題が解けているとする。この状態で、容量制限が4で品物A、Bを選べる場合の解は、次の考え方で求めることができる。  ・容量制限が4で品物Aだけを選べる小問題の解は、表2から8であることが分かる(下線①部分)。  ・品物A、Bを選べる場合、品物Bの容積が2であるので、4から2を減じた容量制限2で品物A、Bを選べる小問題の価値合計6(下線②部分)に、品物Bの価値6を加えた12の価値合計を得られることが分かる。  ・8と12を比較し、大きい方の12を、容量制限4の場合の価値合計として表2に記入する。これは、最後に品物Bを選んだことを意味する。  表2の空白の部分をこの手順に従って順に埋めていくと、容量制限が5のときの価値合計は14であることが分かる。  容量制限4の場合に最後に品物Bを選んだように、各容量制限の小問題を解いたときに最後に選んだ品物を表3に示す。
応用情報技術者試験(平成29年度 秋期 午後 問03 表03)
 容量制限5では、最後に品物Bを選んだことが分かる。次に、品物Bの容積を引いた容量制限3では、最後に品物Bを選んでいる。これを続けていくと、価値合計14を実現する品物の組合せは、品物Aが1個、品物Bが2個であることが分かる。    表1の問題に対して、新たに、容積が3で価値が9である品物Cが追加されたときの問題を解くには、表2に品物A、B、Cを選べる場合の行を追加した表4を順に埋めていけばよい。
応用情報技術者試験(平成29年度 秋期 午後 問03 表04)
〔ナップザック問題に対する動的計画法によるプログラム〕  ナップザック問題に対する動的計画法によるプログラムを図1に示す。なお、Vはナップザックの容量制限、Nは品物の種類の数である。種類s(0~N-1)の品物の容量と価値は、それぞれ、sizes、valuesに格納されている。また、maxvaluetは、容量制限tの小問題の価値合計を保持する配列である。choicetは、容量制限tの小問題を解いたときに最後に選んだ品物を保持するための配列である。この配列は、選んだ品物の組合せを最後に出力するために使用する。なお、全ての配列の添字は0から始まる。
応用情報技術者試験(平成29年度 秋期 午後 問03 図01)
〔計算量に関する検討〕  動的計画法を用いてナップザック問題を解く場合の計算量のオーダは、品物の種類の数をN、ナップザックの容量制限をVとすると、O()である。

設問1品物A, B, Cを選べる問題について、〔動的計画法によるナップザック問題の解法〕に従って、(1)、(2)に答えよ。

(1)表4中のに入れる適切な数値を答えよ。

模範解答

a:6 b:9 c:12 d:15

解説

解答の論理構成

  1. 動的計画法の基本
    【問題文】では「元の容量制限以下の全ての値を容量制限としたときの、品物の種類を限定した問題(以下、小問題という)をあらかじめ解いておき、それらの解を用いる」方法を説明しています。既に「A, Bを選べる」行が完成しているので、ここを土台に「A, B, Cを選べる」行を埋めます。
  2. 比較対象(Cを使わない場合)
    Cを導入しても選ばなければ価値はそのまま「A, Bを選べる」行の値です。容量制限2~5に対し、それぞれ「6」「8」「12」「14」が比較対象となります。
  3. Cを使う場合の計算
    Cのパラメータは【問題文】で「容積が3で価値が9」と定義されています。容量制限 に対して C を最後に選ぶときの価値は
    価値 = 「A, B, Cを選べる」行の ( ) 列の価値 + 9
    になります。
  4. 容量ごとの最大値決定
容量制限 Cを使わない価値Cを使う価値大きい方記入箇所
26― (選べない)6
380+9=99
4122+9=1112
5146+9=1515
  1. 結論
    よって表4の空欄は
    = 6
    = 9
    = 12
    = 15
    となります。

誤りやすいポイント

  • 「容量制限 の値」を取る際に、うっかり上段(A, B 行)の値と足し合わせてしまうミスが多発します。必ず同じ行(A, B, C 行)の左側を参照します。
  • Cを複数個入れられるかを考慮し忘れ、容量5で「9」で止めてしまうケースがあります。無制限個なので 3+2 の組合せも検討し、最適値を再確認する必要があります。
  • 既に完成している行の値をそのままコピーして終わりにしてしまうと、Cを使った場合のより高い価値を見落とします。

FAQ

Q: Cを2個以上入れる場合はどのタイミングで評価するのですか?
A: 現行行の左側列を参照するため、容量6以降で自然に「C+C」などが評価対象になります。今回の容量上限は5なので1個までの評価で済みます。
Q: 行の更新順序は「左から右」でないといけませんか?
A: 無制限個のときは左から右(増える順)で更新することで、同じ種類を繰り返し選ぶケースも正しく反映できます。右から左にすると同一品目を複数回使う可能性が途切れてしまうため不適切です。
Q: 品物数が多い場合でも計算量は現実的ですか?
A: 【問題文】は「O()」と示しており、 です。容量制限 が数千程度なら十分実用的ですが、大きくなるとメモリ・時間ともに増大します。

関連キーワード: 動的計画法、ナップザック、最適化、計算量、配列更新

設問1品物A, B, Cを選べる問題について、〔動的計画法によるナップザック問題の解法〕に従って、(1)、(2)に答えよ。

(2)容量制限が5の場合に最大の価値合計を実現する品物A, B, Cそれぞれの個数を答えよ。

模範解答

A ( 0 )、B ( 1 )、C ( 1 )

解説

解答の論理構成

  1. 追加条件の確認
    問題文で「容積が3で価値が9である品物Cが追加」とあるので、既存の品物A(容積「1」・価値「2」)、品物B(容積「2」・価値「6」)に C(容積「3」・価値「9」)を加えた3種類で考えます。
  2. A, B だけの場合の既知結果
    表4の2行目には「A, Bを選べる」ケースが完成済みで、容量制限「0~5」の価値合計は
    0→「0」、1→「2」、2→「6」、3→「8」、4→「12」、5→「14」
    であることが示されています。
  3. C も選べる行の空欄を動的計画法で埋める
    箱を容量 t とし、C を最後に選ぶか否かで比較します(以下、表4の を順に決定)。
    • t=2:C(容積3)は入らない。よって既存値「6」を採用 ⇒ =6
    • t=3:
      ・C を使わない場合=「8」
      ・C を使う場合=容量 0 の値「0」+C の価値「9」=9
      大きい方は 9 ⇒ =9
    • t=4:
      ・使わない場合=「12」
      ・使う場合=容量1 の値「2」+「9」=11
      大きい方は 12 ⇒ =12
    • t=5:
      ・使わない場合=「14」
      ・使う場合=容量2 の値「6」+「9」=15
      大きい方は 15 ⇒ =15
  4. 容量制限「5」での最終行は 15
    よって表4は
    0,1,2,3,4,5 → 0,2,6,9,12,15
    となります。最大価値合計は「15」。
  5. 最後に選んだ品物を逆追跡
    問題文の手順に従い「最後に選んだ品物」をたどります。
    • t=5 の値 15 は「C を最後に選んだ」結果なので、C を1個採用。残容量=5−3=2
    • t=2 の値 6 は、表3の考え方より「B を最後に選んだ」結果なので、B を1個採用。残容量=2−2=0
    • 残容量 0 では「なし」。
  6. 個数まとめ
    A は0個、B は1個、C は1個。模範解答と一致します。

誤りやすいポイント

  • 比価値(価値/容積)が高い順に選ぶという“貪欲法”を適用すると「B を2個」(価値「12」)で止まり最大値を逃しがちです。
  • 「一つの品物を選ぶ個数には制限がない」という条件を読み落とし、各種類1個ずつだと誤解するケース。
  • 表を埋める際に「C を選ぶ場合は容量 t−3 の“同じ行”の値と足す」手順を忘れ、前行の値を参照してしまうミス。

FAQ

Q: なぜ容量3で「9」を選び、容量4では「12」を残すのですか?
A: 容量3なら C を入れると 0+9=9 で既存 8 を上回りますが、容量4では C を入れると 1+9=11 となり既存 12 を下回るためです。
Q: 品物を何個選んだかはどうやって分かるのですか?
A: 表3と同様に「choice 配列」に“最後に選んだ品物”を記録し、容量からその品物の容積を引きながら逆追跡すると個数が分かります。
Q: 計算量 O() の は何になりますか?
A: 各品物で容量 0~V を一巡するため O(NV) になります。

関連キーワード: 動的計画法、ナップザック、計算量、バックトラッキング、貪欲法

設問2

図1中のに入れる適切な字句を答えよ。

模範解答

オ:t - sizes カ:maxvaluet キ:choicek ク:maxvalueV

解説

解答の論理構成

  1. 変数 temp の計算 ()
    • 目的は「容量制限 t の状態に品物 s を追加した場合の価値合計」を求めることです。
    • 追加前の容量は t から「種類 s の品物の容量」を引いた残りなので、 【問題文】「sizes」を用いて t – sizes と表します。
    • よって t - sizes となります。
  2. 最大価値合計の更新 ()
    • 比較に勝った temp を現在の小問題の解に採用します。
    • この解を保持する配列は【問題文】「maxvaluetは、容量制限tの小問題の価値合計を保持する配列」と明示されています。
    • 従って代入先は maxvaluet、つまり maxvaluet です。
  3. 復元処理で参照する品物番号 ()
    • 復元ループでは「最後に選んだ品物」の配列を逆追跡します。
    • 【問題文】「choicetは…最後に選んだ品物を保持するための配列」とあるので、 現在の容量 k に対して参照すべき添字は choicek
    • したがって choicek です。
  4. 価値合計の最終出力 ()
    • ループ後、最終的な最適価値は「容量制限 V の小問題の解」に等しいです。
    • 【問題文】「maxvaluetは…価値合計を保持する配列」なので、 maxvalueV となります。
以上により模範解答
オ:t - sizes/カ:maxvaluet/キ:choicek/ク:maxvalueV
が導けます。

誤りやすいポイント

  • t - sizes と t + sizes の取り違え
    「残り容量」を求める場面で加算してしまうと配列範囲外アクセスになります。
  • 更新配列を temp や別作業用配列にしてしまう
    DP 表をひとつにまとめているため、正しくは maxvaluet を上書きします。
  • 復元時に size[choicek] ではなく sizek と書いてしまう
    配列 size の添字は「品物番号」であって容量値ではありません。
  • 最終出力を maxvaluek や temp にしてしまう
    復元ループ終了後の k は 0 とは限らず、最適値は常に maxvalueV に残っています。

FAQ

Q: なぜ外側ループが品物 s、内側が容量 t なのですか?
A: 品物を一種類ずつ追加する形式にすると「同一品目を複数個選べる」無限個ナップザックでも正しく更新できます。容量を外側にすると同一品目の多重選択が正しく扱えません。
Q: choice 配列を作らずに価値だけ求めてもよいですか?
A: 最適価値だけで良いなら不要ですが、本問は【問題文】「選んだ品物の組合せを最後に出力するために使用する」とあり、組合せの復元が要求されています。
Q: 計算量 O(NV) がなぜ成り立つのですか?
A: 外側が品物数 N、内側が容量 V を 1 ずつ進める二重ループで、内部は定数時間演算のみなので総ステップ数は 、オーダは O(NV) になります。

関連キーワード: 動的計画法、ナップザック、配列操作、計算量、探索復元

設問3

本文中のに入れる適切な字句を答えよ。

模範解答

ケ:NV

解説

解答の論理構成

  1. 計算量を決めるのは、図1に示された二重ループ部分です。問題文には
    「for(sを0からN−1まで1ずつ増やす)
      for(tをsizesからVまで1ずつ増やす)」
    と明記されています。
  2. 外側の s ループは品物の種類数だけ回りますから回数は N 回になります。
  3. 内側の t ループは、sizes 以上 V 以下を1ずつ進むので最悪でも V 回です。
  4. よって、総反復回数は N × V。ビッグオー表記で
    「動的計画法を用いてナップザック問題を解く場合の計算量のオーダは、品物の種類の数をN、ナップザックの容量制限をVとすると、O()」
    とある には NV を入れるのが妥当です。

誤りやすいポイント

  • 「全探索=指数時間」と早合点して と書いてしまう。動的計画法は指数時間ではなく多項式時間で動く点を見落としがちです。
  • 内側ループが sizes から始まるため平均反復数を考えようとして計算量を小さく見積もる。オーダ評価では最大値(最悪ケース)を取るので V と置くのが原則です。
  • 添字や変数名に惑わされ、NV を逆に書いてしまう。

FAQ

Q: 「sizes から始まるなら内側は V−sizes 回では?」
A: ビッグオーは最高値で評価します。sizes が 1 の品物もあり得るので上限は V 回です。
Q: choice 配列の更新は計算量に影響しますか?
A: 単なる定数時間操作なので二重ループの に吸収され、オーダは増えません。
Q: メモリ使用量のオーダは?
A: maxvalue と choice が長さ V+1 の配列なので です。

関連キーワード: 動的計画法、計算量解析、ビッグオー記法、ナップザック問題、多項式時間
戦国ITクイズ機能

\ せっかくなら /

応用情報技術者
クイズ形式で学習しませんか?

クイズ画面へ遷移する

すぐに利用可能!

©︎2026 情報処理技術者試験対策アプリ

このサイトについてブログプライバシーポリシー利用規約特商法表記開発者について