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

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <queue>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

int main() {

  int POW[21];
  for (int i = 0; i <= 20; i++)
    POW[i] = pow(2, i);

  int N, M;
  scanf("%d %d", &N, &M);

  int *table = new int[N];
  int num[M];
  for (int i = 0; i < M; i++)
    num[i] = 0;

  int **ruisekiwa = new int *[M];
  for (int i = 0; i < M; i++) {
    ruisekiwa[i] = new int[N];
    for (int k = 0; k < N; k++) {
      ruisekiwa[i][k] = 0;
    }
  }

  for (int i = 0; i < N; i++) {
    scanf("%d", &table[i]);
    table[i]--;
    num[table[i]]++;
    ruisekiwa[table[i]][i]++;
  }

  for (int i = 0; i < M; i++) {
    for (int k = 1; k < N; k++) {
      ruisekiwa[i][k] += ruisekiwa[i][k - 1];
    }
  }

  int *dp = new int[POW[M]];

  for (int i = 0; i < POW[M]; i++)
    dp[i] = BIG_NUM;

  dp[0] = 0;

  int next_start_pos, next_state;
  stack<int> S;

  for (int i = 0; i < M; i++) {
    next_state = POW[i];

    int tmp = num[i];
    tmp -= ruisekiwa[i][num[i] - 1];
    dp[next_state] = tmp;
  }

  for (int state = 1; state < POW[M]; state++) {

    next_start_pos = 0;
    for (int loop = 0; loop < M; loop++) {
      if (state & (1 << loop)) {
        next_start_pos += num[loop];
      } else {
        S.push(loop);
      }
    }

    while (!S.empty()) {
      next_state = state + POW[S.top()];

      int tmp = num[S.top()];

      tmp -= (ruisekiwa[S.top()][next_start_pos + num[S.top()] - 1] -
              ruisekiwa[S.top()][next_start_pos - 1]);

      dp[next_state] = min(dp[next_state], dp[state] + tmp);

      S.pop();
    }
  }

  printf("%d\\n", dp[POW[M] - 1]);

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <queue>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

int main() {

  int POW[21];
  for (int i = 0; i <= 20; i++)
    POW[i] = pow(2, i);

  int N, M;
  scanf("%d %d", &N, &M);

  int *table = new int[N];
  int num[M];
  for (int i = 0; i < M; i++)
    num[i] = 0;

  for (int i = 0; i < N; i++) {
    scanf("%d", &table[i]);
    table[i]--;
    num[table[i]]++;
  }

  int *dp = new int[POW[M]];

  for (int i = 0; i < POW[M]; i++)
    dp[i] = BIG_NUM;

  dp[0] = 0;

  int next_start_pos, next_state;
  stack<int> S;

  for (int state = 0; state < POW[M]; state++) {

    next_start_pos = 0;
    for (int loop = 0; loop < M; loop++) {
      if (state & (1 << loop)) {
        next_start_pos += num[loop];
      } else {
        S.push(loop);
      }
    }

    while (!S.empty()) {
      next_state = state + POW[S.top()];

      int tmp = num[S.top()];
      for (int i = 0; i < num[S.top()]; i++) {
        if (table[next_start_pos + i] == S.top()) {
          tmp--;
        }
      }

      dp[next_state] = min(dp[next_state], dp[state] + tmp);

      S.pop();
    }
  }

  printf("%d\\n", dp[POW[M] - 1]);

  return 0;
}