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

#include <bits/stdc++.h>

#define SIZE 300005
#define MOD 1000000007LL
#define INF 1 << 30
#define LLINF 1LL << 60
#define REP(i, n) for (int i = 0; i < n; i++)
#define FOR(i, a, b) for (int i = a; i <= b; i++)
#define DOWN(i, b, a) for (int i = b; i >= a; i--)
#define SET(a, c) memset(a, c, sizeof a)
#define FORALL(i, c)                                                           \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define FOREACH(i, c) for (auto(i) : (c))
#define BIT(i, j) ((i) >> (j)) & 1
#define ALL(o) (o).begin(), (o).end()
#define ERASE(o) (o).erase(unique((o).begin(), (o).end()), (o).end())
#define SQ(x) ((x) * (x))
using namespace std;
typedef long long ll;
typedef valarray<int> Array;
typedef pair<ll, ll> Pll;
typedef pair<int, int> Pii;
typedef pair<double, double> Pdd;
template <typename T> inline void priv(vector<T> a) {
  REP(i, a.size()) {
    cout << a[i];
    if (i == a.size() - 1)
      cout << endl;
    else
      cout << " ";
  }
}
int gcd(int a, int b) {
  int c = max(a, b);
  int d = min(a, b);
  return c == 0 || d == 0 ? c : gcd(c % d, d);
}
int lcm(int a, int b) { return a == 0 || b == 0 ? 0 : a * b / gcd(a, b); }

int W, N;
int v[1010];
int w[1010];

void solve() {
  int dp[1010];
  fill_n(dp, 1010, 0);
  REP(i, N) DOWN(j, W, w[i]) dp[j] = max(dp[j], dp[j - w[i]] + v[i]);
  int ans1 = 0, ans2 = 0;
  DOWN(i, W, 0) if (ans1 <= dp[i]) {
    ans1 = dp[i];
    ans2 = i;
  }
  printf("%d\\n%d\\n", ans1, ans2);
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  for (int c = 1; scanf("%d", &W), W; c++) {
    scanf("%d", &N);
    REP(i, N) scanf("%d,%d", &v[i], &w[i]);
    printf("Case %d:\\n", c);
    solve();
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#define SIZE 300005
#define MOD 1000000007LL
#define INF 1 << 30
#define LLINF 1LL << 60
#define REP(i, n) for (int i = 0; i < n; i++)
#define FOR(i, a, b) for (int i = a; i <= b; i++)
#define DOWN(i, b, a) for (int i = b; i >= a; i--)
#define SET(a, c) memset(a, c, sizeof a)
#define FORALL(i, c)                                                           \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define FOREACH(i, c) for (auto(i) : (c))
#define BIT(i, j) ((i) >> (j)) & 1
#define ALL(o) (o).begin(), (o).end()
#define ERASE(o) (o).erase(unique((o).begin(), (o).end()), (o).end())
#define SQ(x) ((x) * (x))
using namespace std;
typedef long long ll;
typedef valarray<int> Array;
typedef pair<ll, ll> Pll;
typedef pair<int, int> Pii;
typedef pair<double, double> Pdd;
template <typename T> inline void priv(vector<T> a) {
  REP(i, a.size()) {
    cout << a[i];
    if (i == a.size() - 1)
      cout << endl;
    else
      cout << " ";
  }
}
int gcd(int a, int b) {
  int c = max(a, b);
  int d = min(a, b);
  return c == 0 || d == 0 ? c : gcd(c % d, d);
}
int lcm(int a, int b) { return a == 0 || b == 0 ? 0 : a * b / gcd(a, b); }

int W, N;
int v[1010];
int w[1010];
const int NMAX = 1000;
const int VMAX = 10000;
int dp[NMAX * VMAX + 10];

void solve1() {
  int n1 = N / 2;
  int n2 = (N + 1) / 2;
  vector<pair<int, int>> a;
  REP(i, 1 << n1) {
    int sw = 0, sv = 0;
    REP(j, n1) if (i & 1 << j) {
      sw += w[j];
      sv += v[j];
    }
    a.emplace_back(sw, sv);
  }
  sort(a.begin(), a.end());
  int m = 0;
  // for(auto x : a) printf("%d %d\\n",x.first, x.second);
  // FOR(i,1,(1<<n1)-1)
  //   if(a[m].second < a[i].second) a[m++] = a[i];
  // for(auto x : a) printf("%d %d\\n",x.first, x.second);
  int ans1 = 0, ans2 = 0;
  REP(i, 1 << n2) {
    int sw = 0, sv = 0;
    REP(j, n2) if (i & 1 << j) {
      sw += w[j + n1];
      sv += v[j + n1];
    }
    if (sw <= W) {
      auto tmp = (lower_bound(a.begin(), a.end(), make_pair(W - sw, INF)) - 1);
      int tw = tmp->first;
      int tv = tmp->second;
      if (ans1 < sv + tv) {
        ans1 = sv + tv;
        ans2 = sw + tw;
      } else if (ans1 == sv + tv) {
        ans2 = min(ans2, sw + tw);
      }
    }
  }
  printf("%d\\n%d\\n", ans1, ans2);
}

void solve2() {
  int NV = N * 10000;
  fill_n(dp, NV + 1, INF);
  dp[0] = 0;
  REP(i, N) DOWN(j, NV, v[i]) dp[j] = min(dp[j], dp[j - v[i]] + w[i]);
  DOWN(i, NV, 0) if (dp[i] <= W) {
    printf("%d\\n%d\\n", i, dp[i]);
    return;
  }
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  for (int c = 1; scanf("%d", &W), W; c++) {
    scanf("%d", &N);
    REP(i, N) scanf("%d,%d", &v[i], &w[i]);
    printf("Case %d:\\n", c);
    if (N <= 30)
      solve1();
    else
      solve2();
  }
  return 0;
}