DPL_1_C Knapsack Problem

Calendar Clock iconCalendar Clock icon

AOJ

目次

# 問題

http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DPL_1_C

# 解説

ナップサック問題の各アイテムを何回でも選択できるバージョン.
ナップサックの容量を0から順に増やしていき、各容量で最大の選択を記録していく.

各容量での各アイテムの選択で価値が大きくなる方を選択する.

  1. 容量0から最大容量CAPまでのすべての各整数capについて以下を実行する
  2. すべてのアイテムitemについて以下を実行する
    1. もしitemの重さwがcapより大きい場合、何もしない
    2. cap以下の場合は、他のこれまでのitemを考慮して最大値dp[item]とitemの重さw分をcapから取り除いて代わりにitemを入れた場合の価値の大きい方でdp[item]を更新する
  3. dp[CAP]に最大容量CAPでの最大価値が格納されている

# 計算量

O(NCAP)O(N CAP)

# 解答

// C++ 14
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <unordered_map>
#include <math.h>

#define ll long long
#define Int int
#define loop(x, start, end) for(Int x = start; x < end; x++)
#define loopdown(x, start, end) for(int x = start; x > end; x--)
#define rep(n) for(int x = 0; x < n; x++)
#define span(a,x,y) a.begin()+x,a.begin()+y
#define span_all(a) a.begin(),a.end()
#define len(x) (x.size())
#define last(x) (*(x.end()-1))

using namespace std;
#define MAX_N 101
#define MAX_V 1001
#define MAX_CAP 10001

struct Item { Int value, weight; };

Int N, CAP;
vector<Item> items(MAX_N, {-1, -1});
vector<Int> dp(MAX_CAP, 0);
Int v, w;

void input() {
  cin >> N >> CAP;
  loop(n,0,N) {
    cin >> v >> w;
    items[n] = { v, w };
  }
}

void solve() {
  loop(cap,1,CAP+1) {
    loop(n,0,N) {
      if (items[n].weight <= cap)
        dp[cap] = max(dp[cap-items[n].weight] + items[n].value, dp[cap]);
    }
  }
  cout << dp[CAP] << endl;
}

int main(void) {
  input();
  solve();
}

リモートフリーランス。ウェブサービス、スマホアプリエンジニア。
東アジアを拠点に世界を移動しながら活動してます!

お仕事のご依頼・お問い合わせはこちら

コメント