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

#include <bits/stdc++.h>

using namespace std;

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  int n, a, b;
  cin >> n >> a >> b;

  long long mod = 1000000007;

  // a<=b
  if (a > b)
    swap(a, b);

  vector<vector<long long>> dp(n + 1, vector<long long>(b));
  vector<vector<long long>> dp2(n + 1, vector<long long>(b));
  vector<long long> res(n + 1);
  dp[0][0] = 1;
  dp2[0][0] = 0;

  for (int i = 0; i < n; i++) {
    res[i + 1] += (res[i] * 2) % mod;
    res[i + 1] %= mod;

    // add 1
    for (int j = 0; j < n; j++) {
      if ((j + 1) < b) {
        dp[i + 1][j + 1] += dp[i][j];
        dp[i + 1][j + 1] += dp2[i][j];
        dp[i + 1][j + 1] %= mod;
      }
    }
    res[i + 1] += dp[i][b - 1];
    res[i + 1] += dp2[i][b - 1] * 2;
    res[i + 1] %= mod;

    // add 0
    for (int j = 0; j < n; j++) {
      if ((j + 1) < b) {
        dp2[i + 1][j + 1] += dp2[i][j];
        dp2[i + 1][j + 1] %= mod;
      }
      if (j < b) {
        dp[i + 1][0] += dp[i][j];
        dp[i + 1][0] %= mod;
      }
    }
    if ((i + 1 - a) >= 0) {
      for (int j = 1; j < b; j++) {
        dp[i + 1][0] = (dp[i + 1][0] + mod - dp[i + 1 - a][j]) % mod;
      }
      if ((i + 1 - a) == 0)
        dp[i + 1][0] = (dp[i + 1][0] + mod - 1) % mod;
    }

    for (int j = 1; j < n; j++) {
      if ((i + a) > n)
        continue;
      if ((j + a) < b) {
        dp2[i + a][j + a] += dp[i][j];
        dp2[i + a][j + a] %= mod;
      } else if (j < b) {
        res[i + a] += dp[i][j];
        res[i + a] %= mod;
      }
    }
    if (i == 0) {
      if (a < b) {
        dp2[i + a][a] += dp[i][0];
        dp2[i + a][a] %= mod;
      } else {
        res[i + a] += dp[i][0];
        res[i + a] %= mod;
      }
    }
  }
  cout << res[n] << "\\n";
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  int n, a, b;
  cin >> n >> a >> b;

  long long mod = 1000000007;

  // a<=b
  if (a > b)
    swap(a, b);

  // 連続するa以上の0を全て1にしたとき，連続するbが存在するか．
  vector<vector<long long>> dp(n + 1, vector<long long>(n + 1));
  vector<vector<long long>> dp2(n + 1, vector<long long>(n + 1));
  vector<long long> res(n + 1), res2(n + 1);
  dp[0][0] = 1;
  dp2[0][0] = 0;

  for (int i = 0; i < n; i++) {
    res[i + 1] += (res[i] * 2 + res2[i]) % mod;
    res[i + 1] %= mod;

    // add 1
    for (int j = 0; j < n; j++) {
      if ((j + 1) < b) {
        dp[i + 1][j + 1] += dp[i][j];
        dp[i + 1][j + 1] += dp2[i][j];
        dp[i + 1][j + 1] %= mod;
      }
    }
    res[i + 1] += dp[i][b - 1];
    res[i + 1] += dp2[i][b - 1];
    res[i + 1] %= mod;

    for (int j = 1; (i + j) <= n; j++) {
      // add j 0's
      if (j < a) {
        for (int k = 0; k < b; k++) {
          dp2[i + j][0] += dp[i][k];
          dp2[i + j][0] %= mod;
        }
      } else {
        for (int k = 0; k < b; k++) {
          if ((j + k) < b) {
            dp2[i + j][j + k] += dp[i][k];
            dp2[i + j][j + k] %= mod;
          } else {
            res2[i + j] += dp[i][k];
            res2[i + j] %= mod;
          }
        }
      }
    }
  }
  cout << (res[n] + res2[n]) % mod << "\\n";
  return 0;
}