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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
// #include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int SZ = 1005, SZ0 = 256005;

int n, a[SZ], dp[SZ0];
bool bas[SZ];
bool vis[SZ];
int sl, B[SZ], sum[SZ];

template <typename Type> inline void read(Type &xx) {
  Type f = 1;
  char ch;
  xx = 0;
  for (ch = getchar(); ch < '0' || ch > '9'; ch = getchar())
    if (ch == '-')
      f = -1;
  for (; ch >= '0' && ch <= '9'; ch = getchar())
    xx = xx * 10 + ch - '0';
  xx *= f;
}

int DP() {
  for (int i = 1; i <= sl; i++)
    sum[i] = sum[i - 1] + B[i];
  dp[0] = 0;
  for (int i = 1; i <= sl; i++) {
    int mn = B[i];
    for (int j = sum[i] / mn * mn; j >= (mn << 1); j -= mn)
      dp[j] = max(dp[j], dp[j - mn] + 1);
    dp[mn] = max(dp[mn], 1);
  }
  int ans = 0;
  for (int i = 1; i <= sum[sl]; i <<= 1)
    ans = max(ans, dp[i]);
  memset(dp, 0x8f, sizeof dp);
  return ans;
}

bool is_least(int idx) {
  if (vis[a[idx]])
    return false;
  vis[a[idx]] = true;
  for (int j = 1; j <= n; ++j)
    if (a[idx] % a[j] == 0 && bas[a[idx] / a[j]] && a[idx] > a[j])
      return false;
  return true;
}

int main(int argc, char **argv) {
  for (int i = 1; i < SZ; i <<= 1)
    bas[i] = true;
  while (scanf("%d", &n) != EOF && n) {
    memset(dp, 0x8f, sizeof dp);
    memset(vis, 0, sizeof vis);
    for (int i = 1; i <= n; i++)
      read(a[i]);
    int ans = 0;
    for (int i = 1; i <= n; ++i) {
      if (!is_least(i))
        continue;
      sl = 0;
      for (int j = 1; j <= n; ++j)
        if (a[j] % a[i] == 0 && bas[a[j] / a[i]])
          B[++sl] = a[j] / a[i];
      ans = max(ans, DP());
    }
    printf("%d\\n", ans);
  }
  return 0;
}


Error: TLE

Fixed submission:

// By Lin
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>

#define X first
#define Y second
#define mp make_pair
#define sqr(x) ((x) * (x))
#define Rep(i, n) for (int i = 0; i < (n); i++)
#define foreach(it, n)                                                         \\
  for (__typeof(n.begin()) it = n.begin(); it != n.end(); it++)

using namespace std;
typedef long long LL;
typedef pair<int, int> pii;

#define esp 1e-8
#define N 1010
#define MOD 1000000007

int n, a[N], tmp[N], mark[N];
map<int, set<pii>> dp[N];
int main() {
  int tt = 0;
  while (~scanf("%d", &n) && n) {
    Rep(i, n) scanf("%d", &a[i]);
    dp[0].clear();
    dp[0][a[0]].insert(mp(1, -1));
    int ans = 1;
    for (int i = 1; i < n; i++) {
      dp[i].clear();
      dp[i][a[i]].insert(mp(1, i - 1));
      int val = a[i];
      while (dp[i][val].size() != 0) {
        set<pii>::iterator iter = dp[i][val].begin();
        tt++;
        int rVal = iter->X;
        for (int j = dp[i][val].begin()->Y; j >= 0; j--) {
          if (iter != dp[i][val].end() && j == iter->Y) {
            rVal = iter->X;
            iter++;
          }
          foreach (iter, dp[j][val]) {
            tmp[iter->Y + 1] = iter->X + rVal;
            mark[iter->Y + 1] = tt;
            break;
          }
        }
        int cur = 0;
        for (int j = dp[i][val].begin()->Y; j >= -1; j--)
          if (mark[j + 1] == tt && tmp[j + 1] > cur) {
            cur = tmp[j + 1];
            dp[i][val * 2].insert(mp(cur, j));
          }
        val *= 2;
        ans = max(ans, cur);
      }
    }
    printf("%d\\n", ans);
  }
  return 0;
}