Problem p03670 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
int dp[10500000];
int need1[50], need2[50];
int put[10500000], go[10500000][22];
int n, m, k;
int main() {
  int i, j, p, q, a, b, c;
  scanf("%d%d%d", &n, &m, &k);
  for (i = 1; i <= k; i++) {
    scanf("%d%d%d", &a, &b, &c);
    a--, b--;
    need1[a] |= (1 << b);
    need2[a] |= (1 << b) * c;
  }
  n--;
  memset(go, -1, sizeof(go));
  memset(put, -1, sizeof(put));
  for (i = 0; i < (1 << n); i++) {
    int num = 0;
    for (j = 0; j < n; j++)
      if (i & (1 << j)) {
        if (j > 0 && !(i & (1 << (j - 1)))) {
          go[i][num] = i ^ (1 << j) ^ (1 << (j - 1));
        }
        num++;
      }
  }
  for (i = 0; i < (1 << n); i++)
    for (j = n - 1; j >= 0; j--) {
      if ((i & (1 << j)))
        continue;
      put[i] = i ^ (1 << j);
      break;
    }
  dp[0] = 1;
  for (i = 0; i < m; i++) {
    for (j = 0; j < (1 << n); j++)
      if (put[j]) {
        dp[put[j]] += dp[j];
        dp[put[j]] %= 1000000007;
      }
    for (p = 0; p < n; p++)
      for (j = (1 << n) - 1; j >= 0; j--)
        if (go[j][p] != -1) {
          dp[go[j][p]] += dp[j], dp[go[j][p]] %= 1000000007;
        }
    for (j = 0; j < (1 << n); j++)
      if ((j & need1[i]) != need2[i])
        dp[j] = 0;
  }
  int ans = 0;
  for (i = 0; i < (1 << n); i++)
    ans += dp[i], ans %= 1000000007;
  printf("%d\n", ans % 1000000007);
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
using namespace std;
int dp[1048580];
int need1[21], need2[21];
int put[1048580], go[1048580][21];
int n, m, k;
int main() {
  int i, j, p, q, a, b, c;
  scanf("%d%d%d", &n, &m, &k);
  for (i = 1; i <= k; i++) {
    scanf("%d%d%d", &a, &b, &c);
    a--, b--;
    need1[a] |= (1 << b);
    need2[a] |= (1 << b) * c;
  }
  n--;
  memset(go, -1, sizeof(go));
  memset(put, -1, sizeof(put));
  for (i = 0; i < (1 << n); i++) {
    int num = 0;
    for (j = 0; j < n; j++)
      if (i & (1 << j)) {
        if (j > 0 && !(i & (1 << (j - 1)))) {
          go[i][num] = i ^ (1 << j) ^ (1 << (j - 1));
        }
        num++;
      }
  }
  for (i = 0; i < (1 << n); i++)
    for (j = n - 1; j >= 0; j--) {
      if ((i & (1 << j)))
        continue;
      put[i] = i ^ (1 << j);
      break;
    }
  dp[0] = 1;
  for (i = 0; i < m; i++) {
    for (j = 0; j < (1 << n); j++)
      if (put[j]) {
        dp[put[j]] += dp[j];
        dp[put[j]] %= 1000000007;
      }
    for (p = 0; p < n; p++)
      for (j = (1 << n) - 1; j >= 0; j--)
        if (go[j][p] != -1) {
          dp[go[j][p]] += dp[j], dp[go[j][p]] %= 1000000007;
        }
    for (j = 0; j < (1 << n); j++)
      if ((j & need1[i]) != need2[i])
        dp[j] = 0;
  }
  int ans = 0;
  for (i = 0; i < (1 << n); i++)
    ans += dp[i], ans %= 1000000007;
  printf("%d\n", ans % 1000000007);
  return 0;
}