Problem p02316 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cassert>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <list>
#include <vector>

using std::list;
using std::max;
using std::min;
using std::vector;

static const int kMaxWeight = 10000;
static const int kMaxNItem = 100;

int result[kMaxWeight + 1][kMaxNItem + 1];

class Item {
public:
  int value;
  int weight;
  void print() const;
};

void Item::print() const { printf("%d, %d\\n", this->value, this->weight); }

bool gt_value(const Item &a, const Item &b) { return a.value > b.value; }

bool lt_weight(const Item &a, const Item &b) { return a.weight < b.weight; }

int solve(const vector<Item> &items, int weight, int index) {
  if (index < 0 || items.size() <= index || weight < 0) {
    return 0;
  }
  if (result[weight][index] != -1) {
    return result[weight][index];
  }
  int tmp = 0;
  for (int i = 0; 0 <= weight - items.at(index).weight * i; i++) {
    tmp =
        max(tmp, solve(items, weight - items.at(index).weight * i, index - 1) +
                     items.at(index).value * i);
  }
  result[weight][index] = tmp;
  return result[weight][index];
}

void init_result() { memset(result, -1, sizeof(result)); }

void remove_not_unique(vector<Item> &items) {
  std::sort(items.begin(), items.end(), gt_value);
  std::stable_sort(items.begin(), items.end(), lt_weight);
  int weight = 0;
  for (auto &item : items) {
    if (weight == item.weight) {
      item.weight = INT_MAX;
    } else {
      weight = item.weight;
    }
  }
}

int main() {
  init_result();
  int nitem, max_weight;
  scanf("%d%d", &nitem, &max_weight);
  vector<Item> items(nitem);
  for (auto &item : items) {
    scanf("%d%d", &item.value, &item.weight);
  }
  remove_not_unique(items);
  // for(const auto& item : items) {
  // item.print();
  //}
  solve(items, max_weight, items.size() - 1);
  printf("%d\\n", result[max_weight][items.size() - 1]);
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <list>
#include <vector>

using std::list;
using std::max;
using std::min;
using std::vector;

static const int kMaxWeight = 10000;
static const int kMaxNItem = 100;

int result[kMaxWeight + 1][kMaxNItem + 1];

class Item {
public:
  int value;
  int weight;
};

int solve(const vector<Item> &items, int weight, int index) {
  if (index < 0 || items.size() <= index || weight < 0) {
    return 0;
  }
  if (result[weight][index] != -1) {
    return result[weight][index];
  }
  int tmp = 0;
  for (int i = 0; 0 <= weight - items.at(index).weight * i; i++) {
    tmp =
        max(tmp, solve(items, weight - items.at(index).weight * i, index - 1) +
                     items.at(index).value * i);
  }
  result[weight][index] = tmp;
  return result[weight][index];
}

void init_result() { memset(result, -1, sizeof(result)); }

int main() {
  init_result();
  int nitem, max_weight;
  scanf("%d%d", &nitem, &max_weight);
  vector<Item> items(nitem);
  for (auto &item : items) {
    scanf("%d%d", &item.value, &item.weight);
  }
  solve(items, max_weight, items.size() - 1);
  printf("%d\\n", result[max_weight][items.size() - 1]);
  return 0;
}