Problem:
Problem H: Hogemon Get
Problem
がっちょ君は人気のゲームHogemon Getに熱中している。がっちょ君が住んでいる会津国はそれぞれ1から
N
の番号がついている
N
個の町からなる。また、会津国には
M
本の道があり、すべての道は異なる2つの町を結んでいる。がっちょ君は道を双方向に移動することができるが、道以外を通って、ある町から別の町に行くことはできない。
Hogemon Getでは、町
i
でボールを
d
i
個入手することができる。ただし、ある町で再びボールを入手するためには、最後にその町でボールを入手してから15分以上経過している必要がある。なお、がっちょ君は町1、町
N
を含むすべての町を何度でも訪れることができる。
がっちょ君は最初、町1にいて、町
N
に
R
分以内で移動しなければならない。つまり、
R
分後に町
N
にいる必要がある。がっちょ君は移動の際に、最大でいくつのボールを入手することができるだろうか。
Input
入力は以下の形式で与えられる。
N
M
R
d
1
d
2
...
d
N
a
1
b
1
c
1
a
2
b
2
c
2
...
a
M
b
M
c
M
入力はすべて整数である。
1行目に町の個数
N
,道の本数
M
,制限時間
R
が空白区切りで与えられる。
2行目に町
i
(
i
=1,2,...,
N
)に訪れることで入手することができるボールの個数
d
i
が空白区切りで与えられる。
3行目から
M
+2行目に道
j
(
j
=1,2,...,
M
)の情報
a
j
,
b
j
,
c
j
が空白区切りで与えられる。
j
番目の道は町
a
j
と町
b
j
の間を
c
j
分で移動できることを表す。
Constraints
3 ≤
N
≤ 30
N
-1 ≤
M
≤ min(
N
×(
N
-1)/2, 300)
10 ≤
R
≤ 1000
0 ≤
d
i
≤ 10
d
1
=
d
N
= 0
1 ≤
a
j
<
b
j
≤
N
5 ≤
c
j
≤ 100
町1から町
N
へは
R
分以内で移動できることが保証されている
ある2つの町の組に対して2本以上の道があることはない
Output
町1から町
N
へ
R
分以内に移動するまでに入手することができる最大のボールの個数を1行で出力せよ。
Sample Input 1
5 4 40
0 1 1 1 0
1 2 5
2 3 5
3 4 5
4 5 5
Sample Output 1
6
経過時間(分)
町の番号
ボールの数(個)
0
1
0
5
2
1
10
3
2
15
4
3
20
3
3
25
2
4
30
3
5
35
4
6
40
5
6
※経過時間20分の町3では最後に町3でボールを入手してから15分経過していないのでボールを入手することができない。
Sample Input 2
4 3 100
0 3 1 0
1 2 5
2 3 30
3 4 5
Sample Output 2
16
経過時間(分)
町の番号
ボールの数(個)
0
1
0
5
2
3
20
2
6
35
2
9
50
2
12
65
2
15
95
3
16
100
4
16
Sample Input 3
5 4 50
0 1 1 10 0
1 2 10
2 3 10
2 4 10
4 5 10
Sample Output 3
22

Submitted solutions:

code_snippet: #include <bits/stdc++.h>

using namespace std;

const int inf = 1e9;

int main() {

    ios_base::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);    

    int n, m, R;
    cin >> n >> m >> R;

    vector<int> d(n);
    for (auto& x : d) cin >> x;

    vector<vector<int>> w(n, vector<int>(n, inf));
    for (int i = 0; i < n; ++i) w[i][i] = 0;

    for (int u, v, c, i = 0; i < m; ++i) {
        cin >> u >> v >> c;
        --u, --v;
        w[u][v] = min(w[u][v], c);
        w[v][u] = min(w[v][u], c);
    }

    for (int k = 0; k < n; ++k) {
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                w[i][j] = min(w[i][j], w[i][k] + w[k][j]);
            }
        }
    }

    vector<vector<vector<vector<int>>>> dp(R + 1, vector<vector<vector<int>>>(n, vector<vector<int>>(n + 1, vector<int>(2, -inf))));

    int res = 0;
    dp[0][0][n][0] = 0;
    for (int t = 0; t <= R; ++t) {
        for (int last = 0; last < n; ++last) {
            for (int pre_last = 0; pre_last <= n; ++pre_last) {
                for (int st : {0, 1}) {
                    if (last == pre_last) continue;
                    if (dp[t][last][pre_last][st] < 0) continue;

                    {
                        int nt = t + w[last][n - 1];
                        if (nt <= R) res = max(res, dp[t][last][pre_last][st]);
                    }

                    for (int to = 0; to < n; ++to) {
                        if (to == last) {
                            int nt = t + 15;
                            if (nt <= R) {
                                dp[nt][last][pre_last][0] = max(dp[nt][last][pre_last][0], dp[t][last][pre_last][st] + d[last]);
                            }
                        } else if (to == pre_last) {
                            int nt, n_st;
                            if (st == 0) {
                                if (2 * w[last][to] >= 15) nt = t + w[last][to], n_st = 0;
                                else nt = t + 15 - w[last][to], n_st = 1;
                            } else {
                                nt = t + w[last][to];
                                n_st = 0;
                            }
                            if (nt <= R) {
                                dp[nt][pre_last][last][n_st] = max(dp[nt][pre_last][last][n_st], dp[t][last][pre_last][st] + d[pre_last]);
                            }
                        } else {
                            int nt = t + w[last][to];
                            if (nt <= R) {
                                dp[nt][to][last][0] = max(dp[nt][to][last][0], dp[t][last][pre_last][st] + d[to]);
                            }
                        }
                    }
                }
            }
        }
    }

    cout << res << "\n";

    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 55416
final_rank: 5

code_snippet: #include <bits/stdc++.h>

using namespace std;

const int inf = 1e9;

int main() {

#ifdef LOCAL
    freopen("input.txt", "r", stdin);
#endif

    ios_base::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);    

    int n, m, R;
    cin >> n >> m >> R;

    vector<int> d(n);
    for (auto& x : d) cin >> x;

    vector<vector<int>> w(n, vector<int>(n, inf));
    for (int i = 0; i < n; ++i) w[i][i] = 0;

    for (int u, v, c, i = 0; i < m; ++i) {
        cin >> u >> v >> c;
        --u, --v;
        w[u][v] = min(w[u][v], c);
        w[v][u] = min(w[v][u], c);
    }

    for (int k = 0; k < n; ++k) {
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                w[i][j] = min(w[i][j], w[i][k] + w[k][j]);
            }
        }
    }

    vector<vector<vector<vector<int>>>> dp(R + 1, vector<vector<vector<int>>>(n, vector<vector<int>>(n + 1, vector<int>(2, -inf))));

    int res = 0;
    dp[0][0][n][0] = 0;
    for (int t = 0; t <= R; ++t) {
        for (int last = 0; last < n; ++last) {
            for (int pre_last = 0; pre_last <= n; ++pre_last) {
                for (int st : {0, 1}) {
                    if (last == pre_last) continue;
                    if (dp[t][last][pre_last][st] < 0) continue;

                    {
                        int nt = t + w[last][n - 1];
                        if (nt <= R) res = max(res, dp[t][last][pre_last][st]);
                    }

                    for (int to = 0; to < n; ++to) {
                        if (to == last) {
                            int nt = t + 15;
                            if (nt <= R) {
                                dp[nt][last][pre_last][0] = max(dp[nt][last][pre_last][0], dp[t][last][pre_last][st] + d[last]);
                            }
                        } else if (to == pre_last) {
                            int nt, n_st;
                            if (st == 0) {
                                if (2 * w[last][to] >= 15) nt = t + w[last][to], n_st = 0;
                                else nt = t + 15 - w[last][to], n_st = 1;
                            } else {
                                nt = t + w[last][to];
                                n_st = 0;
                            }
                            if (nt <= R) {
                                dp[nt][pre_last][last][n_st] = max(dp[nt][pre_last][last][n_st], dp[t][last][pre_last][st] + d[pre_last]);
                            }
                        } else {
                            int nt = t + w[last][to];
                            if (nt <= R) {
                                dp[nt][to][last][0] = max(dp[nt][to][last][0], dp[t][last][pre_last][st] + d[to]);
                            }
                        }
                    }
                }
            }
        }
    }

    cout << res << "\n";

    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 55348
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int ull;
typedef pair<int, int> pil;
const ll ll_INF = 0x3f3f3f3f3f3f3f3f;
const ll ll_MAX = 0x7fffffffffffffff;
const int int_INF = 0x3f3f3f3f;
const int int_MAX = 0x7fffffff;
const double EPS = 1e-7;
#define R register
#define _max(a, b) ((a) > (b) ? (a) : (b))
#define _min(a, b) ((a) < (b) ? (a) : (b))
#define _abs(a) ((a) > 0 ? (a) : -(a))
#define _swap(a, b) ((a) ^= (b) ^= (a) ^= (b))
#define _eql(x, y) (_abs((x) - (y)) < EPS)
const int MX = 100;
struct Node {
    int v, val;
    int _next;
} e[MX * MX * 2];
int n, m, r;
int head[MX], a[MX], cnt = 0;
void addedge(int u, int v, int val) {
    e[++cnt].v = v;
    e[cnt].val = val;
    e[cnt]._next = head[u];
    head[u] = cnt;
}
int ready[MX] = {0}, have[MX], ans = 0;
void DFS(int u, int now, int res) {
    if(now > r)
        return;
    if(u == n - 1) {
        ans = _max(ans, res);
        return;
    }
    if(ready[u] <= now) {
        int ori = ready[u];
        res += a[u], ready[u] = now + 15;
        for(int i = head[u]; i; i = e[i]._next) {
            DFS(e[i].v, now + e[i].val, res);
        }
        ready[u] = ori;
    }
    else {
        ready[u] += 15;
        DFS(res, ready[u], res + a[u]);
        ready[u] -= 15;
        for(int i = head[u]; i; i = e[i]._next) {
            DFS(e[i].v, now + e[i].val, res);
        }
    }
}
void Init() {
    cin >> n >> m >> r;
    int u, v, val;
    for(int i = 0; i < n; i++) {
        cin >> a[i];
        addedge(i, i, 15);
        // a[i + n] = a[i];
        // if(a[i]) {
        //     addedge(i, i + n, 15);
        //     addedge(i + n, i, 0);
        // }
    }
    for(int i = 0; i < m; i++) {
        cin >> u >> v >> val;
        u--, v--;
        addedge(u, v, val);
        addedge(v, u, val);
    }
}
void solve() {
    DFS(0, 0, 0);
    cout << ans<<endl;
}
int main() {
    std::ios::sync_with_stdio(false);
#ifdef LOCAL
    freopen("data.in", "r", stdin);
    freopen("data.out", "w", stdout);
#endif
    int t = 1;
    while(t--) {
        Init();
        solve();
    }
    return 0;
}
accuracy: 0.04838709677419355
time_ms: 590
memory_kb: 3180
final_rank: 13

code_snippet: /*  -*- coding: utf-8 -*-
 *
 * 1594.cc: Hogemon Get
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_N = 30;
const int MAX_R = 1000;
const int DC = 15;
const int INF = 1 << 29;

/* typedef */

struct Stat {
  int d, lvs[MAX_N];
  Stat(): d(-1) { fill(lvs, lvs + MAX_N, -INF); }
  Stat(int _d): d(_d) { fill(lvs, lvs + MAX_N, -INF); }

  bool operator<(const Stat &s) const {
    if (d != s.d) return (d < s.d);
    for (int i = 0; i < MAX_N; i++)
      if (lvs[i] != s.lvs[i]) return (lvs[i] > s.lvs[i]);
    return false;
  }
};

/* global variables */

int ds[MAX_N], dts[MAX_N][MAX_N];
Stat dp[MAX_R + 1][MAX_N][MAX_N];

/* subroutines */

inline void setmin(int &a, int b) { if (a > b) a = b; }
inline void setmax(int &a, int b) { if (a < b) a = b; }

inline void setdp(int vi, int vj, int vk, int ui, int uj, int uk,
		  int d, int l = -1) {
  Stat udp = dp[ui][uj][uk];
  udp.d = d;
  if (l >= 0) udp.lvs[vj] = l;
  if (dp[vi][vj][vk] < udp) dp[vi][vj][vk] = udp;
}

/* main */

int main() {
  int n, m, r;
  scanf("%d%d%d", &n, &m, &r);

  for (int i = 0; i < n; i++) {
    scanf("%d", ds + i);
    fill(dts[i], dts[i] + n, INF);
    dts[i][i] = 0;
  }

  for (int i = 0; i < m; i++) {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    a--, b--;
    dts[a][b] = dts[b][a] = c;
  }

  for (int k = 0; k < n; k++)
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++)
	setmin(dts[i][j], dts[i][k] + dts[k][j]);

  dp[0][0][0].d = ds[0];
  dp[0][0][0].lvs[0] = 0;

  for (int i = 0; i <= r; i++)
    for (int j = 0; j < n; j++)
      for (int k = 0; k < n; k++) {
	Stat &udp = dp[i][j][k];
	if (udp.d >= 0) {
	  //printf("dp[%d][%d][%d]=%d:", i, j, k, dp[i][j][k]);
	  //for (int l = 0; l < n; l++) printf(" %d", lvu[l]); putchar('\n');

	  if (i < r) {
	    setdp(i + 1, j, k, i, j, k, udp.d);
	    if (j == k && i + DC <= r)
	      setdp(i + DC, j, k, i, j, k, udp.d + ds[j], i + DC);
	  }

	  for (int vj = 0; vj < n; vj++) {
	    int vi = i + dts[j][vj];
	    if (vi > i && vi <= r) {
	      setdp(vi, vj, k, i, j, k, udp.d);
	      if (udp.lvs[vj] + DC <= vi)
		setdp(vi, vj, vj, i, j, k, udp.d + ds[vj], vi);
	    }
	  }
	}
      }

  int maxd = 0;
  for (int i = 0; i <= r; i++)
    for (int k = 0; k < n; k++)
      setmax(maxd, dp[i][n - 1][k].d);

  printf("%d\n", maxd);
  return 0;
}
accuracy: 0.14516129032258066
time_ms: 110
memory_kb: 112312
final_rank: 11

code_snippet: /*  -*- coding: utf-8 -*-
 *
 * 1594.cc: Hogemon Get
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_N = 30;
const int MAX_R = 1000;
const int DC = 15;
const int INF = 1 << 30;

/* typedef */

typedef pair<int,int> pii;
typedef vector<pii> vpii;

struct Stat {
  int d, i, j;
  Stat() {}
  Stat(int _d, int _i, int _j): d(_d), i(_i), j(_j) {}
  bool operator<(const Stat &s) const { return d < s.d; }
};

/* global variables */

int ds[MAX_N], dp[MAX_N][MAX_R + 1], lvs[MAX_N][MAX_R + 1][MAX_N];
vpii nbrs[MAX_N];

/* subroutines */

/* main */

int main() {
  int n, m, r;
  scanf("%d%d%d", &n, &m, &r);

  for (int i = 0; i < n; i++) scanf("%d", ds + i);

  for (int i = 0; i < m; i++) {
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    a--, b--;
    nbrs[a].push_back(pii(b, c));
    nbrs[b].push_back(pii(a, c));
  }

  memset(dp, -1, sizeof(dp));
  fill(lvs[0][0], lvs[0][0] + n, -INF);
  lvs[0][0][0] = 0;
  dp[0][0] = ds[0];

  priority_queue<Stat> q;
  q.push(Stat(ds[0], 0, 0));

  while (! q.empty()) {
    Stat u = q.top(); q.pop();
    if (u.d != dp[u.i][u.j]) continue;

    vpii &nbru = nbrs[u.i];
    int *lvu = lvs[u.i][u.j];
    for (vpii::iterator vit = nbru.begin(); vit != nbru.end(); vit++) {
      int &vi = vit->first, vj = u.j + vit->second;
      if (vj <= r) {
	if (lvu[vi] + DC <= vj) {
	  int vd = u.d + ds[vi];
	  if (dp[vi][vj] < vd) {
	    dp[vi][vj] = vd;
	    memcpy(lvs[vi][vj], lvu, sizeof(lvs[vi][vj]));
	    lvs[vi][vj][vi] = vj;
	    q.push(Stat(vd, vi, vj));
	  }
	}
	else {
	  if (dp[vi][vj] < u.d) {
	    dp[vi][vj] = u.d;
	    memcpy(lvs[vi][vj], lvu, sizeof(lvs[vi][vj]));
	    q.push(Stat(u.d, vi, vj));
	  }

	  if (lvu[vi] + DC <= r) {
	    vj = lvu[vi] + DC;
	    int vd = u.d + ds[vi];
	    if (dp[vi][vj] < vd) {
	      dp[vi][vj] = vd;
	      memcpy(lvs[vi][vj], lvu, sizeof(lvs[vi][vj]));
	      lvs[vi][vj][vi] = vj;
	      q.push(Stat(vd, vi, vj));
	    }
	  }
	}
      }
    }

    if (lvu[u.i] + DC <= r) {
      int vj = lvu[u.i] + DC;
      int vd = u.d + ds[u.i];
      if (dp[u.i][vj] < vd) {
	dp[u.i][vj] = vd;
	memcpy(lvs[u.i][vj], lvu, sizeof(lvs[u.i][vj]));
	lvs[u.i][vj][u.i] = vj;
	q.push(Stat(vd, u.i, vj));
      }
    }
  }

  int maxd = 0;
  for (int j = 0; j <= r; j++)
    if (maxd < dp[n - 1][j]) maxd = dp[n - 1][j];

  printf("%d\n", maxd);
  return 0;
}
accuracy: 0.27419354838709675
time_ms: 10
memory_kb: 4928
final_rank: 10

code_snippet: #include <iostream>
#include <vector>
#include <cstring>

constexpr int MAX_N = 30;
constexpr int MAX_R = 1000;
constexpr int INF   = (1 << 29);

template<class T>
using vec = std::vector<T>;

void update(int &l, int r)
{
    if (l < r) l = r;
}

int main()
{
    int N, M, R;
    std::cin >> N >> M >> R;
    vec<int> ball(N);
    for (int i = 0; i < N; i++) {
        std::cin >> ball[i];
    }
    int d[MAX_N][MAX_N];
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            d[i][j] = (i != j) * INF;
        }
    }
    
    int a, b, c;
    for (int i = 0; i < M; i++) {
        std::cin >> a >> b >> c; a--; b--;
        d[a][b] = d[b][a] = c;
    }

    for (int k = 0; k < N; k++) {
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                d[i][j] = std::min(d[i][j], d[i][k] + d[k][j]);
            }
        }
    }
    
    int res = 0;
    vec<vec<vec<int>>> dp(MAX_R + 1, vec<vec<int>>(MAX_N, vec<int>(MAX_N, -1)));
    dp[0][0][0] = 0;    
    
    for (int i = 0; i <= R; i++) {
        for (int prev = 0; prev < N; prev++) {
            for (int curr = 0; curr < N; curr++) { 
                if (dp[i][curr][prev] == -1 || i + d[curr][N - 1] > R) {
                    continue;
                }
                
                if (i + 15 <= R) {
                    update(dp[i + 15][curr][curr], dp[i][curr][prev] + ball[curr]);
                }
                
                if (curr == N - 1) {
                    update(res, dp[i][curr][prev]);
                }
                
                for (int next = 0; next < N; next++) {
                    if (curr == next) continue;
                    if (prev == next) {
                        if (2 * d[prev][curr] >= 15) {
                            int ni = i + d[prev][curr];
                            if (ni <= R) {
                                update(dp[ni][next][prev],
                                       dp[i][curr][prev] + ball[next]);
                            } 
                        } else {
                            int ni = i + (15 - d[prev][curr]);
                            if (ni <= R) {
                                update(dp[ni][next][prev],
                                       dp[i][curr][prev] + ball[next]);
                            } 
                        }
                    } else {
                        int ni = i + d[curr][next];                        
                        if (ni <= R) {
                            update(dp[ni][next][curr],
                                   dp[i][curr][prev] + ball[next]);
                        }
                    }
                }
            }
        }
    }
    
    std::cout << res << std::endl;
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 7640
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
typedef pair<int,P> PP;
int dp[1111][31][31][9][2][2],a[31];

int main() {
  int n,m,t;
  cin >> n >> m >> t;
  vector<PP> v[n];
  for(int i=0; i<n; i++) cin >> a[i];
  for(int i=0; i<m; i++) {
    int x,y,z;
    cin >> x >> y >> z;
    x--,y--;
    v[x].push_back(PP(y,P(z,a[y])));
    v[y].push_back(PP(x,P(z,a[x])));
    v[x].push_back(PP(x,P(15,a[x])));
    v[y].push_back(PP(y,P(15,a[y])));
  }
  memset(dp,-1,sizeof(dp));
  dp[0][0][0][8][0][0]=0;
  for(int i=0; i<t; i++)
    for(int x=0; x<n; x++)
      for(int j=0; j<n; j++)
        for(int k=5; k<9; k++)
          for(int f=0; f<2; f++)
            for(int h=0; h<2; h++) {
              if(dp[i][x][j][k][f][h]==-1) continue;
              for(int l=0; l<v[x].size(); l++) {
                PP p=v[x][l];
                int y=p.first,c=p.second.first,d=p.second.second;
                if(!h||y!=j) dp[i+c][y][x][min(8,c)][1][f]=max(dp[i+c][y][x][min(8,c)][1][f],dp[i][x][j][k][f][h]+d);
                else {
                  dp[i+c][y][x][min(8,c)][0][f]=max(dp[i+c][y][x][min(8,c)][0][f],dp[i][x][j][k][f][h]);
                  int z=max(0,15-(k<8?k:15)-c);
                  dp[i+c+z][y][x][min(8,c+z)][1][f]=max(dp[i+c+z][y][x][min(8,c+z)][1][f],dp[i][x][j][k][f][h]+d);
                }
              }
            }
  int ans=0;
  for(int i=0; i<=t; i++)
    for(int j=0; j<n; j++)
      for(int k=0; k<9; k++)
        for(int l=0; l<2; l++)
          for(int f=0; f<2; f++) ans=max(ans,dp[i][n-1][j][k][l][f]);
  cout << ans << endl;
  return 0;
}
accuracy: 1
time_ms: 660
memory_kb: 153244
final_rank: 8

code_snippet: #define _USE_MATH_DEFINES
#include <cstdio>
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <complex>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <limits>
#include <climits>
#include <cfloat>
#include <functional>
using namespace std;

class Edge
{
public:
    int to, cost;
    Edge(int to, int cost){
        this->to = to;
        this->cost = cost;
    }
};

bool check(int pos, int t, const vector<pair<int, int> >& v)
{
    for(const auto& p : v){
        if(pos == p.first && t - p.second < 15)
            return false;
    }
    return true;
}

vector<pair<int, int> > normalize(int pos, int t, const vector<pair<int, int> >& v)
{
    vector<pair<int, int> > ans;
    for(const auto& p : v){
        if(pos == p.first){
            if(t - p.second < 15)
                ans.push_back(p);
        }
        else{
            if(t - p.second < 10)
                ans.push_back(p);
        }
    }
    sort(ans.begin(), ans.end());
    return ans;
}

int main()
{
    int n, m, r;
    cin >> n >> m >> r;
    vector<int> d(n);
    for(int i=0; i<n; ++i)
        cin >> d[i];

    vector<vector<Edge> > edges(n);
    for(int i=0; i<m; ++i){
        int a, b, c;
        cin >> a >> b >> c;
        -- a;
        -- b;
        edges[a].push_back(Edge(b, c));
        edges[b].push_back(Edge(a, c));
    }

    vector<pair<int, int> > empty;
    vector<vector<map<vector<pair<int, int> >, int> > > dp(r+1, vector<map<vector<pair<int, int> >, int> >(n));
    dp[0][0][empty] = 0;
    for(int t=0; t<r; ++t){
        for(int curr=0; curr<n; ++curr){
            for(const auto& p : dp[t][curr]){
                vector<pair<int, int> > v = p.first;
                int ball = p.second;
                if(check(curr, t, v)){
                    v.push_back(make_pair(curr, t));
                    ball += d[curr];
                }

                for(const Edge& e : edges[curr]){
                    int next = e.to;
                    int t2 = t + e.cost;
                    if(t2 <= r){
                        auto v2 = normalize(next, t2, v);
                        dp[t2][next][v2] = max(dp[t2][next][v2], ball);
                    }
                }

                int t2;
                for(unsigned i=0; i<v.size(); ++i){
                    if(v[i].first == curr)
                        t2 = v[i].second + 15;
                }
                if(t2 <= r){
                    auto v2 = normalize(curr, t2, v);
                    dp[t2][curr][v2] = max(dp[t2][curr][v2], ball);
                }
            }
        }
    }
    
    int ans = 0;
    for(int t=0; t<=r; ++t){
        for(const auto& p : dp[t][n-1]){
            ans = max(ans, p.second);
        }
    }
    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 1820
memory_kb: 129960
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define FOR(i,a,b) for(int i=a;i<b;i++)
#define REP(i,b) FOR(i,0,b)
#define MP make_pair
#define PB push_back

using ll=long long;
using pii=pair<int,int>;
using vi=vector<int>;
using ld=long double;

int read(){
	int i;
	scanf("%d",&i);
	return i;
}

const int inf=1000000007;
void chmax(int& a,int b){
	if(a<b)
		a=b;
}
void chmin(int& a,int b){
	if(a>b)
		a=b;
}
int c[34][34],d[34];
vi g[34];
int dp[1001][34][34][16];

int main(){
	int n=read(),m=read(),r=read();
	REP(i,n)
		d[i]=read();
	REP(i,n)REP(j,n)c[i][j]=1145;
	REP(i,m){
		int a=read()-1,b=read()-1,_c=read();
		c[a][b]=c[b][a]=_c;
	}
	REP(k,n)REP(i,n)REP(j,n)
		chmin(c[i][j],c[i][k]+c[k][j]);
	REP(t,r+1)REP(i,n)REP(j,n)REP(k,16)
		dp[t][i][j][k]=-inf;
	dp[0][0][0][0]=0;
	REP(t,r){
		REP(i,n)REP(j,n)REP(k,16){
			REP(to,n){
				if(to==i){
					if(t+15<=r)
						chmax(dp[t+15][to][i][15],dp[t][i][j][k]+d[to]);
				}else if(to==j){
					int s=max(0,15-k-c[i][j]);
					if(t+s+c[i][j]<=r)
						chmax(dp[t+s+c[i][j]][to][i][min(15,s+c[i][j])],dp[t][i][j][k]+d[to]);
				}else if(t+c[i][to]<=r)
					chmax(dp[t+c[i][to]][to][i][min(15,c[i][to])],dp[t][i][j][k]+d[to]);
			}
		}
	}
	int ans=0;
	REP(t,r+1)REP(i,n)REP(j,16)
		ans=max(ans,dp[t][n-1][i][j]);
	cout<<ans<<endl;
}
accuracy: 1
time_ms: 1050
memory_kb: 70732
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define for_(i,a,b) for(int i=(a);i<(b);++i)
typedef pair< int, int > pii;
template< typename T > void maxUpdate(T& a, T b) { a = max(a, b); }

struct Edge { int to, c; };

int N, M, R, d[33];
vector< vector< Edge > > edges;

map< vector< pii >, int > dp[1111][33];

bool check(vector< pii >& vec, int u, int c) {
	for (const pii& p : vec) if (p.first == u && p.second > c) return false;
	return true;
}

void solve() {
	dp[0][0][vector< pii >()] = 0;
	
	for_(r,0,R) for_(v,0,N) {
		for (auto it : dp[r][v]) {
			vector< pii > vec = it.first;
			int ball = it.second;
			
			for_(cr,1,16) {
				vector< pii > nxt_vec;
				bool flag = false;
				for (const pii& p : vec) {
					if (p.second > cr) {
						nxt_vec.push_back(pii(p.first, p.second - cr));
						flag |= (p.first == v);
					}
				}
				if (!flag) nxt_vec.push_back(pii(v, 15));
				maxUpdate(dp[r + cr][v][nxt_vec], ball + (check(nxt_vec, v, 0) ? d[v] : 0));
			}
			
			for (const Edge& e : edges[v]) {
				int nxt_ball = ball + (check(vec, e.to, e.c) ? d[e.to] : 0);
				
				vector< pii > nxt_vec;
				bool flag = false;
				for (const pii& p : vec) {
					if (p.second > e.c) {
						nxt_vec.push_back(pii(p.first, p.second - e.c));
						flag |= (p.first == e.to);
					}
				}
				if (!flag) nxt_vec.push_back(pii(e.to, 15));
				
				maxUpdate(dp[r + e.c][e.to][nxt_vec], nxt_ball);
			}
		}
	}
	
	int ans = 0;
	for_(r,0,R+1) for (auto it : dp[r][N-1]) maxUpdate(ans, it.second);
	cout << ans << endl;
}

int main() {
	cin >> N >> M >> R;
	for_(i,0,N) cin >> d[i];
	edges.assign(N, vector< Edge >());
	for_(i,0,M) {
		int a, b, c;
		cin >> a >> b >> c;
		--a; --b;
		edges[a].push_back(Edge{b, c});
		edges[b].push_back(Edge{a, c});
	}
	solve();
}
accuracy: 0.06451612903225806
time_ms: 40
memory_kb: 9808
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;

#define int long long
typedef vector<int>vint;
typedef pair<int,int>pint;
typedef vector<pint>vpint;
#define rep(i,n) for(int i=0;i<(n);i++)
#define reps(i,f,n) for(int i=(f);i<(n);i++)
#define all(v) (v).begin(),(v).end()
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();it++)
#define pb push_back
#define fi first
#define se second
template<typename A,typename B>inline void chmin(A &a,B b){if(a>b)a=b;}
template<typename A,typename B>inline void chmax(A &a,B b){if(a<b)a=b;}

int N,M,R;
int D[30];

vpint G[30];
const int INF=1001001001;
int dist[30][30][2][2001];

typedef tuple<int,int,int,int,int>t5;

signed main(){
    cin>>N>>M>>R;
    rep(i,N)cin>>D[i];
    rep(i,M){
        int a,b,c;
        cin>>a>>b>>c;
        a--;b--;
        G[a].pb(pint(b,c));
        G[b].pb(pint(a,c));
    }

    fill_n(***dist,30*30*2*2001,INF);
    dist[0][0][0][0]=0;
    priority_queue<t5,vector<t5>,greater<t5>>que;
    que.push(make_tuple(0,0,0,0,0));

    while(que.size()){
        int t,v,p,f,c;
        tie(t,v,p,f,c)=que.top();
        que.pop();
        if(dist[v][p][f][c]<t)continue;
        if(t+15<=R&&dist[v][v][1][c+D[v]]>t+15){
            dist[v][v][1][c+D[v]]=t+15;
            que.push(make_tuple(t+15,v,v,1,c+D[v]));
        }

        for(auto &e:G[v]){
            int np;
            if(f)np=v;
            else np=e.fi;
            if(e.fi!=p||e.se*2>=15){
                if(t+e.se>R||dist[e.fi][np][1][c+D[e.fi]]<=t+e.se)continue;
                dist[e.fi][np][1][c+D[e.fi]]=t+e.se;
                que.push(make_tuple(t+e.se,e.fi,np,1,c+D[e.fi]));
            }
            else{
                if(t+e.se>R)continue;
                if(dist[e.fi][np][0][c]>t+e.se){
                    dist[e.fi][np][0][c]=t+e.se;
                    que.push(make_tuple(t+e.se,e.fi,np,0,c));
                }
                int nt=t+e.se+(15-e.se*2);
                if(nt>R)continue;
                if(dist[e.fi][e.fi][1][c+D[e.fi]]>nt){
                    dist[e.fi][e.fi][1][c+D[e.fi]]=nt;
                    que.push(make_tuple(nt,e.fi,e.fi,1,c+D[e.fi]));
                }
            }
        }
    }

    int ans=0;
    rep(i,N)rep(j,2001)rep(k,2)if(dist[N-1][i][k][j]<=R)chmax(ans,j);
    cout<<ans<<endl;
    return 0;
}
accuracy: 1
time_ms: 350
memory_kb: 33604
final_rank: 3

code_snippet: #include "bits/stdc++.h"
using namespace std;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define rer(i,l,u) for(int (i)=(int)(l);(i)<=(int)(u);++(i))
#define reu(i,l,u) for(int (i)=(int)(l);(i)<(int)(u);++(i))
static const int INF = 0x3f3f3f3f; static const long long INFL = 0x3f3f3f3f3f3f3f3fLL;
typedef vector<int> vi; typedef pair<int, int> pii; typedef vector<pair<int, int> > vpii; typedef long long ll;
template<typename T, typename U> static void amin(T &x, U y) { if(y < x) x = y; }
template<typename T, typename U> static void amax(T &x, U y) { if(x < y) x = y; }

int main() {
	int N; int M; int R;
	while(~scanf("%d%d%d", &N, &M, &R)) {
		vector<int> d(N);
		for(int i = 0; i < N; ++ i)
			scanf("%d", &d[i]);
		vector<vi> dist(N, vi(N, INF));
		vector<vpii> adj(N);
		rep(i, M) {
			int a; int b; int c;
			scanf("%d%d%d", &a, &b, &c), -- a, -- b;
			amin(dist[a][b], c);
			amin(dist[b][a], c);
			adj[a].emplace_back(b, c);
			adj[b].emplace_back(a, c);
		}
		rep(i, N) amin(dist[i][i], 0);
		rep(k, N) rep(i, N) rep(j, N)
			amin(dist[i][j], dist[i][k] + dist[k][j]);
		const int T = 15;
		const int X = N + 1;
		vector<vi> dpp(R + 1, vi(X * X * T, -1));
		auto dp = [&dpp, X, T](int r, int i, int j, int t) -> int& {
			return dpp[r][(i * X + j) * T + t];
		};
		dp(0, 0, N, 0) = 0;
		int ans = -1;
		rep(r, R + 1) rep(i, X) rep(j, X) rep(t, T) {
			int x = dp(r, i, j, t);
			if(x == -1) continue;
			if(r + dist[i][N - 1] <= R)
				amax(ans, x);
			if(j != N && t + dist[i][j] >= T) {
				amax(dp(r, i, N, 0), x);
				continue;
			}
			rep(k, N) if(k != i && k != j) {
				int c = dist[i][k];
				if(r + c <= R) {
					if(c >= T)
						amax(dp(r + c, k, N, 0), x + d[k]);
					else
						amax(dp(r + c, k, i, c), x + d[k]);
				}
			}
			if(r + T <= R)
				amax(dp(r + T, i, N, 0), x + d[i]);
			if(j != N) {
				int c = T - dist[i][j];
				if(r + c <= R)
					amax(dp(r + c, j, i, c), x + d[j]);
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 59384
final_rank: 6

code_snippet: #include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

typedef int _loop_int;
#define REP(i,n) for(_loop_int i=0;i<(_loop_int)(n);++i)
#define FOR(i,a,b) for(_loop_int i=(_loop_int)(a);i<(_loop_int)(b);++i)
#define FORR(i,a,b) for(_loop_int i=(_loop_int)(b)-1;i>=(_loop_int)(a);--i)

#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define DEBUG_VEC(v) cout<<#v<<":";REP(i,v.size())cout<<" "<<v[i];cout<<endl
#define ALL(a) (a).begin(),(a).end()

#define CHMIN(a,b) a=min((a),(b))
#define CHMAX(a,b) a=max((a),(b))

// mod
const ll MOD = 1000000007ll;
#define FIX(a) ((a)%MOD+MOD)%MOD

// floating
typedef double Real;
const Real EPS = 1e-11;
#define EQ0(x) (abs(x)<EPS)
#define EQ(a,b) (abs(a-b)<EPS)
typedef complex<Real> P;

int n,m,r;
int d[35];
int g[35][35];
vi gg[35];
// pos,time,prev -> max num
int dp[35][1252][35][2];
const int INF = 830252521;

int main(){
  scanf("%d%d%d",&n,&m,&r);
  REP(i,n)scanf("%d",d+i);
  REP(i,n)REP(j,n)g[i][j] = INF;
  REP(i,n)g[i][i] = 0;
  REP(i,m){
    int a,b,c;
    scanf("%d%d%d",&a,&b,&c);
    --a;--b;
    g[a][b] = g[b][a] = c;
    gg[a].push_back(b);
    gg[b].push_back(a);
  }
  REP(i,n)REP(j,r+1)REP(k,n)REP(b,2)dp[i][j][k][b] = -INF;
  dp[0][0][0][0] = 0;
  REP(tm,r+1)REP(pos,n)REP(prv,n)REP(b,2){
    int now = dp[pos][tm][prv][b];
    if(now<0)continue;
    // printf("%d %d %d %d -> %d\n",tm,pos,prv,b,now);
    int prvlast = g[pos][prv];
    REP(i,gg[pos].size()){
      int to = gg[pos][i];
      int nxtprv = pos;
      if(b)nxtprv = to;
      if(to==prv){
        if(prvlast*2 >= 15){
          // go
          CHMAX(dp[to][tm+prvlast][nxtprv][0],now+d[to]);
        }else{
          // no wait
          CHMAX(dp[to][tm+prvlast][nxtprv][1],now);
          // wait and go
          CHMAX(dp[to][tm+15-prvlast][to][0],now+d[to]);
        }
      }else{
        // go
        CHMAX(dp[to][tm+g[pos][to]][nxtprv][0],now+d[to]);
      }
    }
    // all wait
    CHMAX(dp[pos][tm+15][pos][0],now+d[pos]);
  }
  int ans = 0;
  REP(tm,r+1)REP(prv,n)REP(b,2)CHMAX(ans,dp[n-1][tm][prv][b]);
  printf("%d\n",ans);
  return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 11240
final_rank: 2