Problem p02978 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
#define ri register int
typedef long long ll;
#define rll register ll
namespace io {
const int SIZE = (1 << 21) + 1;
char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c,
                                       qu[55];
int f, qr;
// getchar
#define gc()                                                                   \
  (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, SIZE, stdin),                 \
               (iS == iT ? EOF : *iS++))                                       \
            : *iS++)
// print the remaining part
inline void flush() {
  fwrite(obuf, 1, oS - obuf, stdout);
  oS = obuf;
}
// putchar
inline void putc(char x) {
  *oS++ = x;
  if (oS == oT)
    flush();
}
// input a signed integer
template <class I> inline void gi(I &x) {
  for (f = 1, c = gc(); c < '0' || c > '9'; c = gc())
    if (c == '-')
      f = -1;
  for (x = 0; c <= '9' && c >= '0'; c = gc())
    x = (x << 1) + (x << 3) + (c & 15);
  x *= f;
}
// input a signed integer
template <class I> inline void read(I &x, int p) {
  for (c = gc(); c < '0' || c > '9'; c = gc())
    ;
  for (x = 0; c <= '9' && c >= '0'; c = gc())
    x = ((x << 1) + (x << 3) + (c & 15)) % p;
}
// print a signed integer
template <class I> inline void print(I x) {
  if (!x)
    putc('0');
  if (x < 0)
    putc('-'), x = -x;
  while (x)
    qu[++qr] = x % 10 + '0', x /= 10;
  while (qr)
    putc(qu[qr--]);
}
// no need to call flush at the end manually!
struct Flusher_ {
  ~Flusher_() { flush(); }
} io_flusher_;
} // namespace io
using io ::gi;
using io ::print;
using io ::putc;
using io ::read;
const int N = 20;
const ll inf = 1e18;
int a[N];
#define pii pair<int, int>
#define mp make_pair
map<pii, ll> f[N][N];
inline ll dfs(ri i, ri j, ri x, ri y) {
  if (f[i][j][mp(x, y)])
    return f[i][j][mp(x, y)];
  if (i + 1 == j)
    return 0;
  rll ans = inf;
  for (ri k = i + 1; k <= j - 1; ++k)
    ans = min(ans,
              (ll)a[k] * (x + y) + dfs(i, k, x, x + y) + dfs(k, j, x + y, y));
  return f[i][j][mp(x, y)] = ans;
}
int main() {
  ri n, i;
  gi(n);
  for (i = 1; i <= n; ++i)
    gi(a[i]);
  printf("%lld\n", dfs(1, n, 1, 1) + a[1] + a[n]);
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define ri register int
typedef long long ll;
#define rll register ll
namespace io {
const int SIZE = (1 << 21) + 1;
char ibuf[SIZE], *iS, *iT, obuf[SIZE], *oS = obuf, *oT = oS + SIZE - 1, c,
                                       qu[55];
int f, qr;
// getchar
#define gc()                                                                   \
  (iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, SIZE, stdin),                 \
               (iS == iT ? EOF : *iS++))                                       \
            : *iS++)
// print the remaining part
inline void flush() {
  fwrite(obuf, 1, oS - obuf, stdout);
  oS = obuf;
}
// putchar
inline void putc(char x) {
  *oS++ = x;
  if (oS == oT)
    flush();
}
// input a signed integer
template <class I> inline void gi(I &x) {
  for (f = 1, c = gc(); c < '0' || c > '9'; c = gc())
    if (c == '-')
      f = -1;
  for (x = 0; c <= '9' && c >= '0'; c = gc())
    x = (x << 1) + (x << 3) + (c & 15);
  x *= f;
}
// input a signed integer
template <class I> inline void read(I &x, int p) {
  for (c = gc(); c < '0' || c > '9'; c = gc())
    ;
  for (x = 0; c <= '9' && c >= '0'; c = gc())
    x = ((x << 1) + (x << 3) + (c & 15)) % p;
}
// print a signed integer
template <class I> inline void print(I x) {
  if (!x)
    putc('0');
  if (x < 0)
    putc('-'), x = -x;
  while (x)
    qu[++qr] = x % 10 + '0', x /= 10;
  while (qr)
    putc(qu[qr--]);
}
// no need to call flush at the end manually!
struct Flusher_ {
  ~Flusher_() { flush(); }
} io_flusher_;
} // namespace io
using io ::gi;
using io ::print;
using io ::putc;
using io ::read;
const int N = 20;
const ll inf = 1e18;
int a[N];
#define pii pair<int, int>
#define mp make_pair
map<pii, ll> f[N][N];
inline ll dfs(ri i, ri j, ri x, ri y) {
  if (f[i][j].find(mp(x, y)) != f[i][j].end())
    return f[i][j][mp(x, y)];
  if (i + 1 == j)
    return 0;
  rll ans = inf;
  for (ri k = i + 1; k <= j - 1; ++k)
    ans = min(ans,
              (ll)a[k] * (x + y) + dfs(i, k, x, x + y) + dfs(k, j, x + y, y));
  return f[i][j][mp(x, y)] = ans;
}
int main() {
  ri n, i;
  gi(n);
  for (i = 1; i <= n; ++i)
    gi(a[i]);
  printf("%lld\n", dfs(1, n, 1, 1) + a[1] + a[n]);
  return 0;
}