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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define rep(i, n) for ((i) = 0; (i) < (int)(n); (i)++)
#define foreach(itr, c)                                                        \\
  for (__typeof((c).begin()) itr = (c).begin(); itr != (c).end(); itr++)

#define MAX 1000010
#define INF (1 << 29)

int N, X;
int a[30], dp[MAX];
bool isprime[MAX];

void sieve() {
  int i, j;

  rep(i, MAX) isprime[i] = true;
  isprime[0] = isprime[1] = false;
  for (i = 2; i * i <= MAX; i++)
    if (isprime[i]) {
      for (j = 2 * i; j <= MAX; j += i)
        isprime[j] = false;
    }
}

int main() {
  int i, j, k;

  sieve();

  for (;;) {
    scanf("%d %d", &N, &X);
    if (N == 0 && X == 0)
      break;
    rep(i, N) scanf("%d", &a[i]);

    rep(i, MAX) dp[i] = INF;
    dp[0] = 0;

    int res = 0;
    rep(i, N) {
      for (j = 0; j <= X; j++)
        if (j - a[i] >= 0 && dp[j] > dp[j - a[i]] + 1) {
          dp[j] = dp[j - a[i]] + 1;
          if (isprime[j])
            res = max(res, j);
        }
    }

    if (res == 0)
      cout << "NA" << endl;
    else
      cout << res << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define rep(i, n) for ((i) = 0; (i) < (int)(n); (i)++)
#define foreach(itr, c)                                                        \\
  for (__typeof((c).begin()) itr = (c).begin(); itr != (c).end(); itr++)

#define MAX 1000100

int n, x;
int a[35], dp[MAX];
bool isprime[MAX];

void sieve() {
  int i, j;

  rep(i, MAX) isprime[i] = true;
  isprime[0] = isprime[1] = false;
  for (i = 2; i * i <= MAX; i++)
    if (isprime[i]) {
      for (j = 2 * i; j <= MAX; j += i)
        isprime[j] = false;
    }
}

int dfs(int depth, int v) { // how to pruning???
  int i;

  if (dp[v] != -1)
    return dp[v];
  if (depth == n) {
    if (isprime[v])
      return v;
    else
      return 0;
  }

  int K = ((x - v) / a[depth]) + 1, ret = 0;
  rep(i, K) {
    int tmp = v + i * a[depth];
    ret =
        max(ret, max(dfs(depth + 1, v),
                     dfs(depth + 1, tmp))); // constant multiple get or not get
  }

  return dp[v] = ret;
}

int main() {
  int i, j, k;

  sieve();

  for (;;) {
    scanf("%d %d", &n, &x);
    if (n == 0 && x == 0)
      break;
    rep(i, n) scanf("%d", &a[i]);

    rep(i, MAX) dp[i] = -1;

    int res = dfs(0, 0);
    if (res == 0)
      cout << "NA" << endl;
    else
      cout << res << endl;
    /*
        rep(i,MAX) dp[i] = 0;

        int res = 0;
        rep(i,n) for(j = 0; j <= x; j++){
          if(!isprime[j]) continue;
          int K = ((x-j) / a[i]) + 1;
          rep(k,K) if(j - k*a[i] >= 0) if(dp[j] < dp[j-k*a[i]] + k*a[i]){
            dp[j] = dp[j-k*a[i]] + k*a[i];
            res = ;
          }
        }

        cout << res << endl;
        */
  }

  return 0;
}