Problem:
Problem G: Picnic
Problem
明日はいよいよマイヅ小学校の遠足の日である。マイヅ小学校に通うがっちょ君は、楽しみのあまり明日のお菓子を買い忘れていたことに気づいた。 がっちょ君は遠足を最大限楽しむため、お菓子にもこだわりたい。
がっちょ君はお母さんから$X$円のお小遣いをもらってお菓子を買いに行く。ただし、小学校のルールで遠足に持っていくお菓子の合計金額は$Y$円までと決まっており、$Y$円を上回るとお菓子は全て先生に取り上げられてしまう。
がっちょ君の住む学区には$N$個の町があり、各町には1軒の駄菓子屋がある。各町には1から$N$の番号が割り振られており、がっちょ君は町1に住んでいる。 各駄菓子屋ではいくつかのお菓子が売っており、1つあたりの値段、1つ買うごとにがっちょ君が得られる満足度が決まっている。ただし、各お菓子の在庫数には限りがある。 また、がっちょ君は2つの町の間を移動するとき公共交通機関を利用するため、町$i$から町$j$へ直接移動するには$d_{i,j}$円だけお金がかかる。
最初、がっちょ君は町1にいる。がっちょ君は移動にかかる費用の合計と買ったお菓子の値段の合計の和が$X$円以内で、かつ、買ったお菓子の値段の合計が$Y$円以内になるようにお菓子を買いに行く。最後には町1に到着している必要がある。がっちょ君は買ったお菓子の満足度の合計ができるだけ大きくなるようにしたい。がっちょ君が最適な行動をしたときの満足度の合計を求めよ。
Input
入力は以下の形式ですべて整数で与えられる。
$N$ $X$ $Y$
町1の駄菓子屋の情報
町2の駄菓子屋の情報
...
町$N$の駄菓子屋の情報
$d_{1,1}$ $d_{1,2}$ ... $d_{1,N}$
$d_{2,1}$ $d_{2,2}$ ... $d_{2,N}$
...
$d_{N,1}$ $d_{N,2}$ ... $d_{N,N}$
1行目に町の数$N$と所持金$X$、お菓子を買うために使うことができる上限金額$Y$が空白区切りで与えられる。
2行目からは$N$個の各駄菓子屋の情報が与えられる。
続く$N$行$N$列に町$i$と町$j$を直接行き来するために必要な金額$d_{i,j}$が空白区切りで与えられる。
各町の駄菓子屋の情報は以下の形式で与えられる。
$K$
$a_1$ $b_1$ $c_1$
$a_2$ $b_2$ $c_2$
...
$a_K$ $b_K$ $c_K$
1行目にその駄菓子屋で売っているお菓子の種類の数$K$が与えられる。続く$K$行にお菓子の1つの値段$a_i$、1つあたりの満足度$b_i$、在庫数$c_i$が空白区切りで与えられる。
Constraints
入力は以下の条件を満たす。
$1 \leq N \leq 14$
$1 \leq X \leq 10000$
$1 \leq Y \leq min(1000,X)$
$1 \leq K \leq 300$
$1 \leq a_i \leq 1000$
$1 \leq b_i \leq 1000$
$1 \leq c_i \leq 1000$
$0 \leq d_{i,j} \leq 10000$
$d_{i,i} = 0$
Output
満足度の合計の最大値を1行に出力する。
Sample Input 1
1 10 10
3
1 10 1
2 20 2
3 30 3
0
Sample Output 1
100
Sample Input 2
2 10 10
3
1 10 1
2 20 2
3 30 3
1
5 200 1
0 2
3 0
Sample Output 2
200
Sample Input 3
3 10 10
1
1 1 1
1
3 3 3
1
5 5 5
0 1 0
1 0 0
0 1 0
Sample Output 3
10
Sample Input 4
4 59 40
1
7 6 3
1
10 3 9
2
9 8 5
7 6 10
4
8 2 9
1 7 1
7 7 9
1 2 3
0 28 7 26
14 0 10 24
9 6 0 21
9 24 14 0
Sample Output 4
34

Submitted solutions:

code_snippet: // AOJ #3019 Picnic
// 2025.3.24

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(ll n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

const int INF = 1e9;
const int NEG = -1000000000;

typedef vector<int> VI;

int main(){
    int n = Cin(), X = Cin(), Y = Cin();

    vector<vector<tuple<int,int,int>>> shop(n);
    for (int i = 0; i < n; i++){
        int k = Cin();
        shop[i].resize(k);
        for (int j = 0; j < k; j++){
            int a = Cin(), b = Cin(), c = Cin();
            shop[i][j] = {a,b,c};
        }
    }

    vector<vector<int>> d(n, vector<int>(n));
    for (int i = 0; i < n; i++){
        for (int j = 0; j < n; j++) d[i][j] = Cin();
    }

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

    int Nmask = 1 << n;
    vector<vector<int>> dpTSP(Nmask, vector<int>(n, INF));
    dpTSP[1<<0][0] = 0;
    for (int mask = 0; mask < Nmask; mask++){
        for (int i = 0; i < n; i++){
            if(dpTSP[mask][i] == INF) continue;
            for (int j = 0; j < n; j++){
                if(mask & (1 << j)) continue;
                int nmask = mask | (1 << j);
                dpTSP[nmask][j] = min(dpTSP[nmask][j], dpTSP[mask][i] + d[i][j]);
            }
        }
    }
    vector<int> trav(Nmask, INF);
    for (int mask = 0; mask < Nmask; mask++){
        if(!(mask & 1)) continue;
        for (int i = 0; i < n; i++){
            if(dpTSP[mask][i] < INF){
                trav[mask] = min(trav[mask], dpTSP[mask][i] + d[i][0]);
            }
        }
    }

    vector<VI> f(n, VI(Y+1, 0));
    for (int i = 0; i < n; i++){
        for(auto &t : shop[i]){
            int a, b, cnt;
            tie(a, b, cnt) = t;
            int k = 1;
            while(cnt > 0){
                int num = min(k, cnt);
                cnt -= num;
                int cost = a * num, sat = b * num;
                for (int c = Y; c >= cost; c--){
                    f[i][c] = max(f[i][c], f[i][c - cost] + sat);
                }
                k <<= 1;
            }
        }
        for (int c = 1; c <= Y; c++) f[i][c] = max(f[i][c], f[i][c-1]);
    }

    int m = n/2;
    int sizeA = 1 << m;
    vector<VI> dpA(sizeA, VI(Y+1, NEG));
    dpA[0][0] = 0;
    for (int mask = 1; mask < sizeA; mask++){
        int i = __builtin_ctz(mask);
        int pm = mask ^ (1 << i);
        if(pm == 0){
            for (int c = 0; c <= Y; c++) dpA[mask][c] = f[i][c];
        } else {
            for (int c = 0; c <= Y; c++) dpA[mask][c] = NEG;
            for (int c1 = 0; c1 <= Y; c1++){
                if(dpA[pm][c1] == NEG) continue;
                for (int c2 = 0; c1 + c2 <= Y; c2++)
                    dpA[mask][c1+c2] = max(dpA[mask][c1+c2], dpA[pm][c1] + f[i][c2]);
            }
            for (int c = 1; c <= Y; c++)
                dpA[mask][c] = max(dpA[mask][c], dpA[mask][c-1]);
        }
    }

    int szB = 1 << (n - m);
    vector<VI> dpB(szB, VI(Y+1, NEG));
    dpB[0][0] = 0;
    for (int mask = 1; mask < szB; mask++){
        int i = __builtin_ctz(mask);
        int pm = mask ^ (1 << i);
        int town = m + i;
        if(pm == 0){
            for (int c = 0; c <= Y; c++) dpB[mask][c] = f[town][c];
        } else {
            for (int c = 0; c <= Y; c++) dpB[mask][c] = NEG;
            for (int c1 = 0; c1 <= Y; c1++){
                if(dpB[pm][c1] == NEG) continue;
                for (int c2 = 0; c1 + c2 <= Y; c2++)
                    dpB[mask][c1+c2] = max(dpB[mask][c1+c2], dpB[pm][c1] + f[town][c2]);
            }
            for (int c = 1; c <= Y; c++)
                dpB[mask][c] = max(dpB[mask][c], dpB[mask][c-1]);
        }
    }

    int ans = 0;
    for (int mask = 0; mask < Nmask; mask++){
        if(!(mask & 1)) continue;
        if(trav[mask] > X) continue;
        int allowed = min(Y, X - trav[mask]);
        int maskA = mask & ((1 << m) - 1);
        int maskB = mask >> m;
        int best = 0;
        for (int costA = 0; costA <= allowed; costA++){
            int costB = allowed - costA;
            int vA = dpA[maskA][costA];
            int vB = dpB[maskB][costB];
            if(vA == NEG || vB == NEG) continue;
            best = max(best, vA + vB);
        }
        ans = max(ans, best);
    }

    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 5572
final_rank: 1

code_snippet: #include <bits/stdc++.h>
#define INF (int)(1e8)
using namespace std;

static int n, x, y;
static vector<int> dist;
static vector<vector<int>> memo, dp, d;

inline unsigned long long pcnt(unsigned long long u) {
    u = ((u & 0xaaaaaaaaaaaaaaaaULL) >> 1) + (u & 0x5555555555555555ULL);
    u = ((u & 0xccccccccccccccccULL) >> 2) + (u & 0x3333333333333333ULL);
    u = ((u & 0xf0f0f0f0f0f0f0f0ULL) >> 4) + (u & 0x0f0f0f0f0f0f0f0fULL);
    u = ((u & 0xff00ff00ff00ff00ULL) >> 8) + (u & 0x00ff00ff00ff00ffULL);
    u = ((u & 0xffff0000ffff0000ULL) >> 16) + (u & 0x0000ffff0000ffffULL);
    u = ((u & 0xffffffff00000000ULL) >> 32) + (u & 0x00000000ffffffffULL);
    return u;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin >> n >> x >> y;
    memo.resize(n);
    for (int i = 0; i < n; i++) {
        memo[i].assign(y + 1, 0);
        int K; cin >> K;
        for (int j = 0; j < K; j++) {
            int A,B,C; cin >> A >> B >> C;
            for (int p = 0; C; p++) {
                int now = min((1 << p), C);
                for (int l = y; l >= now * A; l--)
                    memo[i][l] = max(memo[i][l], memo[i][l - now * A] + now * B);
                C -= now;
            }
        }
    }
    d.resize(n, vector<int>(n));
    for (int i=0;i<n;i++) for(int j=0;j<n;j++) cin>>d[i][j];
    for (int k=0;k<n;k++) for(int i=0;i<n;i++) for(int j=0;j<n;j++) d[i][j]=min(d[i][j], d[i][k]+d[k][j]);

    vector<vector<int>> bitdp(1<<n, vector<int>(n, INF));
    bitdp[1][0]=0;
    for (int mask=1; mask<(1<<n); mask++) {
        for (int u=0; u<n; u++) if ((mask>>u)&1) {
            for (int v=0; v<n; v++) if(!((mask>>v)&1))
                bitdp[mask|(1<<v)][v]=min(bitdp[mask|(1<<v)][v], bitdp[mask][u]+d[u][v]);
        }
    }
    dist.assign(1<<n, INF);
    for (int mask=0; mask<(1<<n); mask++)
        for (int u=0; u<n; u++)
            dist[mask]=min(dist[mask], bitdp[mask][u]+d[u][0]);

    dp.assign(1<<n, vector<int>(y+1,0));
    for (int sub=1; sub<(1<<(n>>1)); sub++) {
        int id=__builtin_ctzll(sub);
        for (int c=0;c<=y;c++){
            for(int c2=0;c2+c<=y;c2++)
                dp[sub][c+c2]=max(dp[sub][c+c2], dp[sub^(1<<id)][c]+memo[id][c2]);
        }
        for (int c=1;c<=y;c++) dp[sub][c]=max(dp[sub][c],dp[sub][c-1]);
    }

    for (int sub=1; sub<(1<<((n+1)>>1)); sub++) {
        int id=__builtin_ctzll(sub);
        for (int c=0;c<=y;c++){
            for(int c2=0;c2+c<=y;c2++)
                dp[sub<<(n>>1)][c+c2]=max(dp[sub<<(n>>1)][c+c2], dp[(sub^(1<<id))<<(n>>1)][c]+memo[id+(n>>1)][c2]);
        }
        for (int c=1;c<=y;c++) dp[sub<<(n>>1)][c]=max(dp[sub<<(n>>1)][c],dp[sub<<(n>>1)][c-1]);
    }

    int ans=0;
    for (int mask=1; mask<(1<<n); mask++) {
        if(!((mask>>0)&1)) continue;
        int route=dist[mask];
        if (route>x) continue;
        int lv=min(y,x-route);
        int half=0;
        for (int j=0;j<(n>>1);j++) if ((mask>>j)&1) half|=1<<j;
        for (int c=0;c<=lv;c++)
            ans=max(ans, dp[half][c]+dp[(mask^half)][lv-c]);
    }

    cout<<ans<<"\n";
    return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 69068
final_rank: 13

code_snippet: #include <bits/stdc++.h>
#define inf (int)(1e8)
using namespace std;

unsigned long long popcount(unsigned long long x) {
  x = ((x & 0xaaaaaaaaaaaaaaaaUL) >> 1) + (x & 0x5555555555555555UL);
  x = ((x & 0xccccccccccccccccUL) >> 2) + (x & 0x3333333333333333UL);
  x = ((x & 0xf0f0f0f0f0f0f0f0UL) >> 4) + (x & 0x0f0f0f0f0f0f0f0fUL);
  x = ((x & 0xff00ff00ff00ff00UL) >> 8) + (x & 0x00ff00ff00ff00ffUL);
  x = ((x & 0xffff0000ffff0000UL) >> 16) + (x & 0x0000ffff0000ffffUL);
  x = ((x & 0xffffffff00000000UL) >> 32) + (x & 0x00000000ffffffffUL);
  return x;
}

int n, x, y;
vector<int> dist;
vector<vector<int>> memo, dp, d;

int solve();

int main() {
  cin >> n >> x >> y;
  memo.resize(n);
  for (int i = 0; i < n; ++i) {
    memo[i].assign(y + 1, 0);
    int k;
    cin >> k;
    for (int j = 0; j < k; ++j) {
      int a, b, c;
      cin >> a >> b >> c;
      for (int p = 0; c; ++p) {
        int now = min(1 << p, c);
        for (int l = y; l >= now * a; --l)
          memo[i][l] = max(memo[i][l], memo[i][l - now * a] + now * b);
        c -= now;
      }
    }
  }
  d.resize(n, vector<int>(n));
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < n; ++j) cin >> d[i][j];
  for (int k = 0; k < n; ++k)
    for (int i = 0; i < n; ++i)
      for (int j = 0; j < n; ++j) d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
  cout << solve() << endl;
  return 0;
}

int solve() {
  {  // bitdp
    vector<vector<int>> bitdp(1 << n, vector<int>(n, inf));
    bitdp[1][0] = 0;
    for (int i = 1; i < (1 << n); ++i)
      for (int j = 0; j < n; ++j)
        if (i >> j & 1)
          for (int k = 0; k < n; ++k)
            bitdp[i | (1 << k)][k] =
                min(bitdp[i | (1 << k)][k], bitdp[i][j] + d[j][k]);
    dist.assign(1 << n, inf);
    for (int i = 0; i < (1 << n); ++i)
      for (int j = 0; j < n; ++j) dist[i] = min(dist[i], bitdp[i][j] + d[j][0]);
  }
  int res = 0;
  dp.assign(1 << n, vector<int>(y + 1, 0));
  // pre
  for (int i = 1; i < (1 << (n >> 1)); ++i) {
    int id = __builtin_ctzll(i);
    for (int j = 0; j <= y; ++j)
      for (int k = 0; k + j <= y; ++k)
        dp[i][j + k] = max(dp[i][j + k], dp[i ^ (1 << id)][j] + memo[id][k]);
    for (int j = 1; j <= y; ++j) dp[i][j] = max(dp[i][j], dp[i][j - 1]);
  }
  // suf
  for (int i = 1; i < (1 << ((n + 1) >> 1)); ++i) {
    int id = __builtin_ctzll(i);
    for (int j = 0; j <= y; ++j)
      for (int k = 0; k + j <= y; ++k)
        dp[i << (n >> 1)][j + k] =
            max(dp[i << (n >> 1)][j + k],
                dp[(i ^ (1 << id)) << (n >> 1)][j] + memo[id + (n >> 1)][k]);
    for (int j = 1; j <= y; ++j)
      dp[i << (n >> 1)][j] =
          max(dp[i << (n >> 1)][j], dp[i << (n >> 1)][j - 1]);
  }

  for (int i = 1; i < (1 << n); ++i) {
    int half = 0;
    for (int j = 0; j < (n >> 1); ++j)
      if (i >> j & 1) half |= 1 << j;
    int now = min(x - dist[i], y);
    for (int j = 0; j <= now; ++j)
      res = max(res, dp[half][j] + dp[i ^ half][now - j]);
  }
  return res;
}
accuracy: 1
time_ms: 220
memory_kb: 68120
final_rank: 12

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
using namespace std;

typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 1000000007;
typedef double ld;
typedef complex<ld> Point;
const ll INF = mod * mod;
typedef pair<int, int> P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
typedef vector<int> vec;
typedef vector<string> svec;

int n;
int dp[14][1001];
int dist[14][14];
int dcost[(1 << 14)][14];
int sumcost[1 << 14];

int c1[1 << 7][1001];
int c2[1 << 7][1001];
void solve() {
	cin >> n; int x, y; cin >> x >> y;
	//start_napzack
	rep(i, n) {
		int k; cin >> k;
		rep(j, y+1) {
			dp[i][j] = -mod;
		}
		dp[i][0] = 0;
		rep(j, k) {
			//cost,val,num
			int a, b, c; cin >> a >> b >> c;
			rep(l, a) {
				if (l > y)continue;
				priority_queue<P> q;
				q.push({ dp[i][l],0 });
				int ad = 0;
				for (int loc = l + a; loc <= y; loc += a) {
					ad += b;
					P p = q.top();
					while (true) {
						if (loc / a - p.second > c) {
							q.pop(); p = q.top();
						}
						else break;
					}
					q.push({ dp[i][loc] - ad,loc / a });
					dp[i][loc] = max(dp[i][loc], p.first + ad);
				}
			}
		}
	}
	//end_napzack

	rep(i, n) {
		rep(j, n) {
			cin >> dist[i][j];
		}
	}
	rep(i, (1 << n))rep(j, n)dcost[i][j] = mod;
	dcost[1][0] = 0;
	for (int i = 1; i < (1 << n);i+=2) {
		rep(j, n) {
			rep(k, n) {
				if (i&(1 << k))continue;
				int ni = i ^ (1 << k);
				dcost[ni][k] = min(dcost[ni][k], dcost[i][j] + dist[j][k]);
			}
		}
	}
	rep(i, (1 << n)) {
		sumcost[i] = mod;
		rep(j, n) {
			sumcost[i] = min(sumcost[i], dcost[i][j] + dist[j][0]);
		}
	}
	int h = n / 2; int h2 = n - h;
	rep(i, (1 << h)) {
		rep(j, y + 1)c1[i][j] = -mod;
		c1[i][0] = 0;
		rep(j, h) {
			if (i&(1 << j)) {
				per(k, y + 1) {
					if (c1[i][k] < 0)continue;
					rep(l, y + 1) {
						if (k + l > y)break;
						c1[i][k + l] = max(c1[i][k + l], c1[i][k] + dp[j][l]);
					}
				}
			}
		}
		rep1(j, y) {
			c1[i][j] = max(c1[i][j], c1[i][j - 1]);
		}
	}
	rep(i, (1 << h2)) {
		rep(j, y + 1)c2[i][j] = -mod;
		c2[i][0] = 0;
		rep(j, h2) {
			if (i&(1 << j)) {
				per(k, y + 1) {
					if (c2[i][k] < 0)continue;
					rep(l, y + 1) {
						if (k + l > y)break;
						c2[i][k + l] = max(c2[i][k + l], c2[i][k] + dp[j + h][l]);
					}
				}
			}
		}
		rep1(j, y) {
			c2[i][j] = max(c2[i][j], c2[i][j - 1]);
		}
	}
	int mid = (1 << h);
	int ans = 0;
	for (int i = 1; i < (1 << n); i += 2) {
		int sc = sumcost[i];
		sc = x - sc;
		if (sc > y)sc = y;
		int r = sc;
		int li = i % mid; int ri = i / mid;
		rep(j, r + 1) {
			int s = c1[li][j] + c2[ri][r - j];
			ans = max(ans, s);
		}
	}
	cout << ans << endl;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(5);
	//while (cin >> n>>h>>m>>s,n)solve();
	solve();
	//stop
	return 0;
}
accuracy: 1
time_ms: 260
memory_kb: 5376
final_rank: 5

code_snippet: #include <bits/stdc++.h>
#define inf (int)(1e8)
using namespace std;

unsigned long long popcount(unsigned long long x) {
  x = ((x & 0xaaaaaaaaaaaaaaaaUL) >> 1) + (x & 0x5555555555555555UL);
  x = ((x & 0xccccccccccccccccUL) >> 2) + (x & 0x3333333333333333UL);
  x = ((x & 0xf0f0f0f0f0f0f0f0UL) >> 4) + (x & 0x0f0f0f0f0f0f0f0fUL);
  x = ((x & 0xff00ff00ff00ff00UL) >> 8) + (x & 0x00ff00ff00ff00ffUL);
  x = ((x & 0xffff0000ffff0000UL) >> 16) + (x & 0x0000ffff0000ffffUL);
  x = ((x & 0xffffffff00000000UL) >> 32) + (x & 0x00000000ffffffffUL);
  return x;
}

int n, x, y;
vector<int> dist;
vector<vector<int>> memo, dp, d;

int solve();

int main() {
  cin >> n >> x >> y;
  memo.resize(n);
  for (int i = 0; i < n; ++i) {
    memo[i].assign(y + 1, 0);
    int k;
    cin >> k;
    for (int j = 0; j < k; ++j) {
      int a, b, c;
      cin >> a >> b >> c;
      for (int p = 0; c; ++p) {
        int now = min(1 << p, c);
        for (int l = y; l >= now * a; --l)
          memo[i][l] = max(memo[i][l], memo[i][l - now * a] + now * b);
        c -= now;
      }
    }
  }
  d.resize(n, vector<int>(n));
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < n; ++j) cin >> d[i][j];
  for (int k = 0; k < n; ++k)
    for (int i = 0; i < n; ++i)
      for (int j = 0; j < n; ++j) d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
  cout << solve() << endl;
  return 0;
}

int solve() {
  {  // bitdp
    vector<vector<int>> bitdp(1 << n, vector<int>(n, inf));
    bitdp[1][0] = 0;
    for (int i = 1; i < (1 << n); ++i)
      for (int j = 0; j < n; ++j)
        if (i >> j & 1)
          for (int k = 0; k < n; ++k)
            bitdp[i | (1 << k)][k] =
                min(bitdp[i | (1 << k)][k], bitdp[i][j] + d[j][k]);
    dist.assign(1 << n, inf);
    for (int i = 0; i < (1 << n); ++i)
      for (int j = 0; j < n; ++j) dist[i] = min(dist[i], bitdp[i][j] + d[j][0]);
  }
  int res = 0;
  dp.assign(1 << n, vector<int>(y + 1, 0));
  // pre
  for (int i = 1; i < (1 << (n >> 1)); ++i) {
    int id = __builtin_ctzll(i);
    for (int j = 0; j <= y; ++j)
      for (int k = 0; k + j <= y; ++k)
        dp[i][j + k] = max(dp[i][j + k], dp[i ^ (1 << id)][j] + memo[id][k]);
    for (int j = 1; j <= y; ++j) dp[i][j] = max(dp[i][j], dp[i][j - 1]);
  }
  // suf
  for (int i = 1; i < (1 << ((n + 1) >> 1)); ++i) {
    int id = __builtin_ctzll(i);
    for (int j = 0; j <= y; ++j)
      for (int k = 0; k + j <= y; ++k)
        dp[i << (n >> 1)][j + k] =
            max(dp[i << (n >> 1)][j + k],
                dp[(i ^ (1 << id)) << (n >> 1)][j] + memo[id + (n >> 1)][k]);
    for (int j = 1; j <= y; ++j)
      dp[i << (n >> 1)][j] =
          max(dp[i << (n >> 1)][j], dp[i << (n >> 1)][j - 1]);
  }

  for (int i = 1; i < (1 << n); ++i) {
    int half = 0;
    for (int j = 0; j < (n >> 1); ++j)
      if (i >> j & 1) half |= 1 << j;
    int now = min(x - dist[i], y);
    for (int j = 0; j <= now; ++j)
      res = max(res, dp[half][j] + dp[i ^ half][now - j]);
  }
  return res;
}
accuracy: 1
time_ms: 220
memory_kb: 67984
final_rank: 11

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define SIZE 15

struct Data{
	Data(int arg_price,int arg_value,int arg_num){
		price = arg_price;
		value = arg_value;
		num = arg_num;
	}
	int price,value,num;
};

struct Info{

	int num_item;
	vector<Data> V;
};

int N,X,Y;
int POW[SIZE];
int min_dist[SIZE][SIZE];
int TSP[1 << 14][SIZE];
int dp_each[SIZE][305][1005],dp_each2[SIZE][1005];
int dp_A[1 << 7][1005],dp_B[1 << 7][1005];
Info info[SIZE];


int main(){

	POW[0] = 1;
	for(int i = 1; i < SIZE; i++){

		POW[i] = POW[i-1]*2;
	}

	scanf("%d %d %d",&N,&X,&Y);

	int price,value,num;

	for(int i = 0; i < N; i++){

		scanf("%d",&info[i].num_item);
		for(int k = 0; k < info[i].num_item; k++){

			scanf("%d %d %d",&price,&value,&num);
			info[i].V.push_back(Data(price,value,num));
		}
	}

	for(int i = 0; i < N; i++){
		for(int k = 0; k < N; k++){

			scanf("%d",&min_dist[i][k]);
		}
	}

	for(int i = 0; i < N; i++){ //14

		for(int k = 0; k <= info[i].num_item; k++){
			for(int p = 0; p <= Y; p++){
				dp_each[i][k][p] = -BIG_NUM;
			}
		}

		for(int k = 0; k <= Y; k++){

			dp_each2[i][k] = -BIG_NUM;
		}

		dp_each[i][0][0] = 0;
		dp_each2[i][0] = 0;

		for(int k = 0; k < info[i].num_item; k++){ //300

			for(int p = 0; p <= Y; p++){

				dp_each[i][k+1][p] = dp_each[i][k][p];
			}

			int num = info[i].V[k].num;
			int mult;

			for(int p = 1; num > 0; p *= 2){
				mult = min(p,num);
				for(int w = Y; w-mult*info[i].V[k].price >= 0; w--){
					if(dp_each[i][k+1][w-mult*info[i].V[k].price] == -BIG_NUM)continue;
					dp_each[i][k+1][w] = max(dp_each[i][k+1][w],
							dp_each[i][k+1][w-mult*info[i].V[k].price]+mult*info[i].V[k].value);
					dp_each2[i][w] = max(dp_each2[i][w],dp_each[i][k+1][w]);
				}
				num -= mult;
			}
		}

		for(int k = 1; k <= Y; k++){

			dp_each2[i][k] = max(dp_each2[i][k],dp_each2[i][k-1]);
		}
	}

	if(N == 1){

		printf("%d\n",dp_each2[0][Y]);
		return 0;
	}

	//ワーシャルフロイド
	for(int mid = 0; mid < N; mid++){
		for(int start = 0; start < N; start++){
			for(int goal = 0; goal < N; goal++){

				min_dist[start][goal] = min(min_dist[start][goal],min_dist[start][mid]+min_dist[mid][goal]);
			}
		}
	}

	//TSP
	for(int state = 0; state < POW[N]; state++){
		for(int town = 0; town < N; town++){

			TSP[state][town] = BIG_NUM;
		}
	}

	TSP[1][0] = 0;
	for(int state = 1; state < POW[N];state++){
		for(int town = 0; town < N; town++){
			if(TSP[state][town] == BIG_NUM)continue;

			for(int loop = 0; loop < N; loop++){
				if(state & (1 << loop))continue;

				int next_state = state+POW[loop];
				int next_dist = TSP[state][town]+min_dist[town][loop];

				TSP[next_state][loop] = min(TSP[next_state][loop],next_dist);
			}
		}
	}

	vector<int> A,B;
	for(int i = 0; i < N/2; i++){

		A.push_back(i);
	}
	for(int i = N/2; i < N; i++){

		B.push_back(i);
	}

	for(int i = 0; i < POW[A.size()]; i++){
		for(int k = 0; k <= Y; k++){

			dp_A[i][k] = -BIG_NUM;
		}
	}
	dp_A[0][0] = 0;

	for(int state = 0; state < POW[A.size()]; state++){
		for(int i = 0; i <= Y; i++){
			if(dp_A[state][i] == -BIG_NUM)continue;

			for(int loop = 0; loop < A.size(); loop++){
				if(state & (1 << loop))continue;

				for(int k = 0; k <= Y; k++){
					if(i+k > Y)break;

					int next_state = state+POW[loop];
					int next_value = dp_A[state][i]+dp_each2[A[loop]][k];

					dp_A[next_state][i+k] = max(dp_A[next_state][i+k],next_value);
				}
			}
		}

		for(int i = 1; i <= Y; i++){

			dp_A[state][i] = max(dp_A[state][i],dp_A[state][i-1]);
		}
	}

	for(int i = 0; i < POW[B.size()]; i++){
		for(int k = 0; k <= Y; k++){

			dp_B[i][k] = -BIG_NUM;
		}
	}
	dp_B[0][0] = 0;

	for(int state = 0; state < POW[B.size()]; state++){
		for(int i = 0; i <= Y; i++){
			if(dp_B[state][i] == -BIG_NUM)continue;

			for(int loop = 0; loop < B.size(); loop++){
				if(state & (1 << loop))continue;

				for(int k = 0; k <= Y; k++){
					if(i+k > Y)break;

					int next_state = state+POW[loop];
					int next_value = dp_B[state][i]+dp_each2[B[loop]][k];

					dp_B[next_state][i+k] = max(dp_B[next_state][i+k],next_value);
				}
			}
		}

		for(int i = 1; i <= Y; i++){

			dp_B[state][i] = max(dp_B[state][i],dp_B[state][i-1]);
		}
	}

	int ans = 0;

	for(int state_A = 1; state_A < POW[A.size()]; state_A++){

		int num_A = 0;
		for(int loop = 0; loop < A.size(); loop++){
			if(state_A & (1 << loop)){
				num_A += POW[A[loop]];
			}
		}

		for(int state_B = 0; state_B < POW[B.size()]; state_B++){

			int num_B = 0;
			for(int loopB = 0; loopB < B.size(); loopB++){
				if(state_B & (1 << loopB)){
					num_B += POW[B[loopB]];
				}
			}

			int all_state = num_A+num_B;
			int path_cost = BIG_NUM;

			for(int i = 0; i < N; i++){
				if(!(POW[i]&all_state))continue;

				path_cost = min(path_cost,TSP[all_state][i]+min_dist[i][0]);
			}

			int limit = Y;
			if(X-Y < path_cost){

				limit = Y-(path_cost-(X-Y));
			}

			for(int budget_A = 0; budget_A <= limit; budget_A++){
				int budget_B = limit-budget_A;

				ans = max(ans,dp_A[state_A][budget_A]+dp_B[state_B][budget_B]);
			}
		}
	}

	printf("%d\n",ans);

	return 0;
}
accuracy: 1
time_ms: 620
memory_kb: 21948
final_rank: 10

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
using namespace std;

typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 1000000007;
typedef double ld;
typedef complex<ld> Point;
const ll INF = mod * mod;
typedef pair<int, int> P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
typedef vector<int> vec;
typedef vector<string> svec;

int n;
int dp[14][1001];
int dist[14][14];
int dcost[(1 << 14)][14];
int sumcost[1 << 14];

int c1[1 << 7][1001];
int c2[1 << 7][1001];
void solve() {
	cin >> n; int x, y; cin >> x >> y;
	//start_napzack
	rep(i, n) {
		int k; cin >> k;
		rep(j, y+1) {
			dp[i][j] = -mod;
		}
		dp[i][0] = 0;
		rep(j, k) {
			//cost,val,num
			int a, b, c; cin >> a >> b >> c;
			rep(l, a) {
				if (l > y)continue;
				priority_queue<P> q;
				q.push({ dp[i][l],0 });
				int ad = 0;
				for (int loc = l + a; loc <= y; loc += a) {
					ad += b;
					P p = q.top();
					while (true) {
						if (loc / a - p.second > c) {
							q.pop(); p = q.top();
						}
						else break;
					}
					q.push({ dp[i][loc] - ad,loc / a });
					dp[i][loc] = max(dp[i][loc], p.first + ad);
				}
			}
		}
	}
	//end_napzack

	rep(i, n) {
		rep(j, n) {
			cin >> dist[i][j];
		}
	}
	rep(i, (1 << n))rep(j, n)dcost[i][j] = mod;
	dcost[1][0] = 0;
	for (int i = 1; i < (1 << n);i+=2) {
		rep(j, n) {
			rep(k, n) {
				if (i&(1 << k))continue;
				int ni = i ^ (1 << k);
				dcost[ni][k] = min(dcost[ni][k], dcost[i][j] + dist[j][k]);
			}
		}
	}
	rep(i, (1 << n)) {
		sumcost[i] = mod;
		rep(j, n) {
			sumcost[i] = min(sumcost[i], dcost[i][j] + dist[j][0]);
		}
	}
	int h = n / 2; int h2 = n - h;
	rep(i, (1 << h)) {
		rep(j, y + 1)c1[i][j] = -mod;
		c1[i][0] = 0;
		rep(j, h) {
			if (i&(1 << j)) {
				per(k, y + 1) {
					if (c1[i][k] < 0)continue;
					rep(l, y + 1) {
						if (k + l > y)break;
						c1[i][k + l] = max(c1[i][k + l], c1[i][k] + dp[j][l]);
					}
				}
			}
		}
		rep1(j, y) {
			c1[i][j] = max(c1[i][j], c1[i][j - 1]);
		}
	}
	rep(i, (1 << h2)) {
		rep(j, y + 1)c2[i][j] = -mod;
		c2[i][0] = 0;
		rep(j, h2) {
			if (i&(1 << j)) {
				per(k, y + 1) {
					//if (c2[i][k] < 0)continue;
					rep(l, y + 1) {
						if (k + l > y)break;
						c2[i][k + l] = max(c2[i][k + l], c2[i][k] + dp[j + h][l]);
					}
				}
			}
		}
		rep1(j, y) {
			c2[i][j] = max(c2[i][j], c2[i][j - 1]);
		}
	}
	int mid = (1 << h);
	int ans = 0;
	for (int i = 1; i < (1 << n); i += 2) {
		int sc = sumcost[i];
		sc = x - sc;
		if (sc > y)sc = y;
		int r = sc;
		int li = i % mid; int ri = i / mid;
		rep(j, r + 1) {
			int s = c1[li][j] + c2[ri][r - j];
			ans = max(ans, s);
		}
	}
	cout << ans << endl;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(5);
	//while (cin >> n>>h>>m>>s,n)solve();
	solve();
	stop
	return 0;
}
accuracy: 1
time_ms: 470
memory_kb: 5152
final_rank: 8

code_snippet: #include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<complex>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
using namespace std;

typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 1000000007;
typedef double ld;
typedef complex<ld> Point;
const ll INF = mod * mod;
typedef pair<int, int> P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
const ld eps = 1e-8;
const ld pi = acos(-1.0);
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
typedef vector<int> vec;
typedef vector<string> svec;

int n;
int dp[14][1001];
int dist[14][14];
int dcost[(1 << 14)][14];
int sumcost[1 << 14];

int c1[1 << 7][1001];
int c2[1 << 7][1001];
void solve() {
	cin >> n; int x, y; cin >> x >> y;
	//start_napzack
	rep(i, n) {
		int k; cin >> k;
		rep(j, y+1) {
			dp[i][j] = -mod;
		}
		dp[i][0] = 0;
		rep(j, k) {
			//cost,val,num
			int a, b, c; cin >> a >> b >> c;
			rep(l, a) {
				if (l > y)continue;
				priority_queue<P> q;
				q.push({ dp[i][l],0 });
				int ad = 0;
				for (int loc = l + a; loc <= y; loc += a) {
					ad += b;
					P p = q.top();
					while (true) {
						if (loc / a - p.second > c) {
							q.pop(); p = q.top();
						}
						else break;
					}
					q.push({ dp[i][loc] - ad,loc / a });
					dp[i][loc] = max(dp[i][loc], p.first + ad);
				}
			}
		}
	}
	//end_napzack

	rep(i, n) {
		rep(j, n) {
			cin >> dist[i][j];
		}
	}
	rep(i, (1 << n))rep(j, n)dcost[i][j] = mod;
	dcost[1][0] = 0;
	for (int i = 1; i < (1 << n);i+=2) {
		rep(j, n) {
			rep(k, n) {
				if (i&(1 << k))continue;
				int ni = i ^ (1 << k);
				dcost[ni][k] = min(dcost[ni][k], dcost[i][j] + dist[j][k]);
			}
		}
	}
	rep(i, (1 << n)) {
		sumcost[i] = mod;
		rep(j, n) {
			sumcost[i] = min(sumcost[i], dcost[i][j] + dist[j][0]);
		}
	}
	int h = n / 2; int h2 = n - h;
	rep(i, (1 << h)) {
		rep(j, y + 1)c1[i][j] = -mod;
		c1[i][0] = 0;
		rep(j, h) {
			if (i&(1 << j)) {
				per(k, y + 1) {
					if (c1[i][k] < 0)continue;
					rep(l, y + 1) {
						if (k + l > y)break;
						c1[i][k + l] = max(c1[i][k + l], c1[i][k] + dp[j][l]);
					}
				}
			}
		}
		rep1(j, y) {
			c1[i][j] = max(c1[i][j], c1[i][j - 1]);
		}
	}
	rep(i, (1 << h2)) {
		rep(j, y + 1)c2[i][j] = -mod;
		c2[i][0] = 0;
		rep(j, h2) {
			if (i&(1 << j)) {
				per(k, y + 1) {
					if (c2[i][k] < 0)continue;
					rep(l, y + 1) {
						if (k + l > y)break;
						c2[i][k + l] = max(c2[i][k + l], c2[i][k] + dp[j + h][l]);
					}
				}
			}
		}
		rep1(j, y) {
			c2[i][j] = max(c2[i][j], c2[i][j - 1]);
		}
	}
	int mid = (1 << h);
	int ans = 0;
	for (int i = 1; i < (1 << n); i += 2) {
		int sc = sumcost[i];
		sc = x - sc;
		if (sc > y)sc = y;
		int r = sc;
		int li = i % mid; int ri = i / mid;
		rep(j, r + 1) {
			int s = c1[li][j] + c2[ri][r - j];
			ans = max(ans, s);
		}
	}
	cout << ans << endl;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(5);
	//while (cin >> n>>h>>m>>s,n)solve();
	solve();
	//stop
	return 0;
}
accuracy: 1
time_ms: 410
memory_kb: 5056
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

using vi = vector<int>;
using vvi = vector<vi>;

const int Y = 1010;
const int INF = 19191919;

struct Town{
    int k;
    vi a,b,c;

    int dp[Y];

    Town(){}

    void init(){
        // read
        cin >>k;
        a.assign(k,0);
        b.assign(k,0);
        c.assign(k,0);
        rep(i,k) scanf(" %d %d %d", &a[i], &b[i], &c[i]);

        // make dp table
        rep(i,Y) dp[i] = -INF;
        dp[0] = 0;
        rep(i,k){
            int rem = c[i];
            int num = 1;

            while(rem>0){
                for(int j=Y-1; j>=0; --j)if(dp[j] > -INF){
                    int nx = j+a[i]*num;
                    if(nx<Y) dp[nx] = max(dp[nx], dp[j]+b[i]*num);
                }

                rem -= num;
                num *= 2;
                if(num > rem) num = rem;
            }
        }

        rep(i,Y-1) dp[i+1] = max(dp[i+1], dp[i]);
    }

    int MAX(int yen){
        return dp[yen];
    }
};

int main(){
    int n,x,y;
    scanf(" %d %d %d", &n, &x, &y);

    vector<Town> t(n);
    rep(i,n) t[i].init();

    vvi d(n, vi(n));
    rep(i,n)rep(j,n) cin >>d[i][j];

    // Floyd-Warshall
    rep(k,n)rep(i,n)rep(j,n) d[i][j] = min(d[i][j], d[i][k]+d[k][j]);

    // calc move cost
    vvi dp(1<<n, vi(n,INF));
    dp[1][0] = 0;
    rep(mask,1<<n)rep(i,n)if(mask>>i&1){
        rep(j,n){
            if(mask>>j&1) continue;
            int nmask = mask|(1<<j);
            dp[nmask][j] = min(dp[nmask][j], dp[mask][i]+d[i][j]);
        }
    }

    vi move_cost(1<<n,INF);
    rep(mask,1<<n){
        rep(i,n) move_cost[mask] = min(move_cost[mask], dp[mask][i]+d[i][0]);
    }

    // two groups
    int A = n/2, B = n-A;

    // groupA : 0 ~ A-1
    vvi dpa(1<<A, vi(Y, -INF));
    dpa[0][0] = 0;
    rep(i,A){
        rep(mask,1<<i){
            int nmask = mask|(1<<i);

            int tidx = i;
            rep(j,Y)if(dp[mask][j] > -INF){
                rep(k,Y){
                    int nj = j+k;
                    if(nj >= Y) break;

                    dpa[nmask][nj] = max(dpa[nmask][nj], dpa[mask][j]+t[tidx].MAX(k));
                }
            }
        }
    }

    // groupB : A ~ A+B-1
    vvi dpb(1<<B, vi(Y, -INF));
    dpb[0][0] = 0;
    rep(i,B){
        rep(mask,1<<i){
            int nmask = mask|(1<<i);

            int tidx = A+i;
            rep(j,Y)if(dp[mask][j] > -INF){
                rep(k,Y){
                    int nj = j+k;
                    if(nj >= Y) break;

                    dpb[nmask][nj] = max(dpb[nmask][nj], dpb[mask][j]+t[tidx].MAX(k));
                }
            }
        }
    }

    // check all masks
    int ans = 0;

    int AA = (1<<A)-1, BB = (1<<B)-1;
    rep(mask,1<<n){
        int amask = mask&AA;
        int bmask = (mask>>A)&BB;

        int cost = move_cost[mask];
        // use ai yen for group A
        rep(ai,y+1){
            int bi = min(y-ai, x-cost-ai);
            if(bi<0) break;

            ans = max(ans, dpa[amask][ai]+dpb[bmask][bi]);
        }
    }

    printf("%d\n", ans);
    return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 5536
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

using vi = vector<int>;
using vvi = vector<vi>;

const int Y = 1010;
const int INF = 19191919;

struct Town{
    int k;
    vi a,b,c;

    int dp[Y];

    Town(){}

    void init(){
        // read
        cin >>k;
        a.assign(k,0);
        b.assign(k,0);
        c.assign(k,0);
        rep(i,k) scanf(" %d %d %d", &a[i], &b[i], &c[i]);

        // make dp table
        rep(i,Y) dp[i] = -INF;
        dp[0] = 0;
        rep(i,k){
            int rem = c[i];
            int num = 1;

            while(rem>0){
                for(int j=Y-1; j>=0; --j)if(dp[j] > -INF){
                    int nx = j+a[i]*num;
                    if(nx<Y) dp[nx] = max(dp[nx], dp[j]+b[i]*num);
                }

                rem -= num;
                num *= 2;
                if(num > rem) num = rem;
            }
        }

        rep(i,Y-1) dp[i+1] = max(dp[i+1], dp[i]);
    }

    int MAX(int yen){
        return dp[yen];
    }
};

int main(){
    int n,x,y;
    scanf(" %d %d %d", &n, &x, &y);

    vector<Town> t(n);
    rep(i,n) t[i].init();

    vvi d(n, vi(n));
    rep(i,n)rep(j,n) cin >>d[i][j];

    // Floyd-Warshall
    rep(k,n)rep(i,n)rep(j,n) d[i][j] = min(d[i][j], d[i][k]+d[k][j]);

    // calc move cost
    vvi dp(1<<n, vi(n,INF));
    dp[1][0] = 0;
    rep(mask,1<<n)rep(i,n)if(mask>>i&1){
        rep(j,n){
            if(mask>>j&1) continue;
            int nmask = mask|(1<<j);
            dp[nmask][j] = min(dp[nmask][j], dp[mask][i]+d[i][j]);
        }
    }

    vi move_cost(1<<n,INF);
    rep(mask,1<<n){
        rep(i,n) move_cost[mask] = min(move_cost[mask], dp[mask][i]+d[i][0]);
    }

    // two groups
    int A = n/2, B = n-A;

    // groupA : 0 ~ A-1
    vvi dpa(1<<A, vi(Y, -INF));
    dpa[0][0] = 0;
    rep(i,A){
        rep(mask,1<<i){
            int nmask = mask|(1<<i);

            int tidx = i;
            rep(j,Y){
                rep(k,Y){
                    int nj = j+k;
                    if(nj >= Y) break;

                    dpa[nmask][nj] = max(dpa[nmask][nj], dpa[mask][j]+t[tidx].MAX(k));
                }
            }
        }
    }

    // groupB : A ~ A+B-1
    vvi dpb(1<<B, vi(Y, -INF));
    dpb[0][0] = 0;
    rep(i,B){
        rep(mask,1<<i){
            int nmask = mask|(1<<i);

            int tidx = A+i;
            rep(j,Y){
                rep(k,Y){
                    int nj = j+k;
                    if(nj >= Y) break;

                    dpb[nmask][nj] = max(dpb[nmask][nj], dpb[mask][j]+t[tidx].MAX(k));
                }
            }
        }
    }

    // check all masks
    int ans = 0;

    int AA = (1<<A)-1, BB = (1<<B)-1;
    rep(mask,1<<n){
        int amask = mask&AA;
        int bmask = (mask>>A)&BB;

        int cost = move_cost[mask];
        // use ai yen for group A
        rep(ai,y+1){
            int bi = min(y-ai, x-cost-ai);
            if(bi<0) break;

            ans = max(ans, dpa[amask][ai]+dpb[bmask][bi]);
        }
    }

    printf("%d\n", ans);
    return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 5452
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

using vi = vector<int>;
using vvi = vector<vi>;

const int Y = 1010;
const int INF = 19191919;

struct Town{
    int k;
    vi a,b,c;

    int dp[Y];

    Town(){}

    void init(){
        // read
        cin >>k;
        a.assign(k,0);
        b.assign(k,0);
        c.assign(k,0);
        rep(i,k) cin >>a[i] >>b[i] >>c[i];

        // make dp table
        rep(i,Y) dp[i] = -INF;
        dp[0] = 0;
        rep(i,k){
            int rem = c[i];
            int num = 1;

            while(rem>0){
                for(int j=Y-1; j>=0; --j)if(dp[j] > -INF){
                    int nx = j+a[i]*num;
                    if(nx<Y) dp[nx] = max(dp[nx], dp[j]+b[i]*num);
                }

                rem -= num;
                num *= 2;
                if(num > rem) num = rem;
            }
        }

        rep(i,Y-1) dp[i+1] = max(dp[i+1], dp[i]);
    }

    int MAX(int yen){
        return dp[yen];
    }
};

int main(){
    int n,x,y;
    cin >>n >>x >>y;

    vector<Town> t(n);
    rep(i,n) t[i].init();

    vvi d(n, vi(n));
    rep(i,n)rep(j,n) cin >>d[i][j];

    // Floyd-Warshall
    rep(k,n)rep(i,n)rep(j,n) d[i][j] = min(d[i][j], d[i][k]+d[k][j]);

    // calc move cost
    vvi dp(1<<n, vi(n,INF));
    dp[1][0] = 0;
    rep(mask,1<<n)rep(i,n)if(mask>>i&1){
        rep(j,n){
            if(mask>>j&1) continue;
            int nmask = mask|(1<<j);
            dp[nmask][j] = min(dp[nmask][j], dp[mask][i]+d[i][j]);
        }
    }

    vi move_cost(1<<n,INF);
    rep(mask,1<<n){
        rep(i,n) move_cost[mask] = min(move_cost[mask], dp[mask][i]+d[i][0]);
    }

    // two groups
    int A = n/2, B = n-A;

    // groupA : 0 ~ A-1
    vvi dpa(1<<A, vi(Y, -INF));
    dpa[0][0] = 0;
    rep(i,A){
        rep(mask,1<<i){
            int nmask = mask|(1<<i);

            int tidx = i;
            rep(j,Y){
                rep(k,Y){
                    int nj = j+k;
                    if(nj >= Y) break;

                    dpa[nmask][nj] = max(dpa[nmask][nj], dpa[mask][j]+t[tidx].MAX(k));
                }
            }
        }
    }

    // groupB : A ~ A+B-1
    vvi dpb(1<<B, vi(Y, -INF));
    dpb[0][0] = 0;
    rep(i,B){
        rep(mask,1<<i){
            int nmask = mask|(1<<i);

            int tidx = A+i;
            rep(j,Y){
                rep(k,Y){
                    int nj = j+k;
                    if(nj >= Y) break;

                    dpb[nmask][nj] = max(dpb[nmask][nj], dpb[mask][j]+t[tidx].MAX(k));
                }
            }
        }
    }

    // check all masks
    int ans = 0;

    int AA = (1<<A)-1, BB = (1<<B)-1;
    rep(mask,1<<n){
        int amask = mask&AA;
        int bmask = (mask>>A)&BB;

        int cost = move_cost[mask];
        // use ai yen for group A
        rep(ai,y+1){
            int bi = min(y-ai, x-cost-ai);
            if(bi<0) continue;

            ans = max(ans, dpa[amask][ai]+dpb[bmask][bi]);
        }
    }

    cout << ans << '\n';
    return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 5432
final_rank: 3

code_snippet: #include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

struct data{
	int bit;
	int cost;
	int v;
	data(){}
	data(int vv,int bb,int cc){
		v=vv;
		cost=cc;
		bit=bb;
	}
	bool operator<(const data &dat)const{
		return cost>dat.cost;
	}
};

int n,x,y;
int dp[1<<14][14];
int dp2[14][1001];
int dp3[1<<14][1001];
int dp4[1<<14][1001];
int tmp[1001][1001];
int tmp2[1001];
int tmp3[15][1001];
int dist[14][14];
int a[14][301],b[14][301],c[14][301];

void dijk(){
	priority_queue<data> que;
	for(int i=0;i<(1<<n);i++){
		for(int j=0;j<n;j++){
			dp[i][j]=100000;
		}
	}
	dp[1][0]=0;
	que.push(data(0,1,0));
	while(que.size()){
		data d=que.top();
		que.pop();
		if(dp[d.bit][d.v]<d.cost)continue;
		for(int nec=0;nec<n;nec++){
			int nbit=d.bit|(1<<nec);
			int ncost=d.cost+dist[d.v][nec];
			if(ncost<dp[nbit][nec]){
				dp[nbit][nec]=ncost;
				que.push(data(nec,nbit,ncost));
			}
		}
	}
}

int main(void){
	scanf("%d%d%d",&n,&x,&y);
	for(int i=0;i<n;i++){
		int k;
		scanf("%d",&k);
		for(int j=0;j<k;j++){
			scanf("%d%d%d",&a[i][j],&b[i][j],&c[i][j]);
		}
		memset(tmp,0,sizeof(tmp));
		for(int j=0;j<k;j++){
			memset(tmp3,0,sizeof(tmp3));
			for(int cs=0;cs<=y;cs++){
				tmp3[0][cs]=tmp[j][cs];
			}
			int cnt2=0;
			for(int ncs=0;ncs<=10;ncs++){
				int cs=min(c[i][j],(int)(1<<ncs));
				c[i][j]-=cs;
				cnt2++;
				for(int l=0;l<=y;l++){
					tmp3[cnt2][l]=max(tmp3[cnt2][l],tmp3[cnt2-1][l]);
					if(l+cs*a[i][j]>y)continue;
					tmp3[cnt2][l+cs*a[i][j]]=max(tmp3[cnt2][l+cs*a[i][j]],tmp3[cnt2-1][l]+b[i][j]*cs);
				}
			}
			for(int l=0;l<=y;l++){
				tmp[j+1][l]=tmp3[cnt2][l];
			}
			
		}
		for(int j=0;j<=y;j++){
			dp2[i][j]=tmp[k][j];
		}
		for(int j=1;j<=y;j++){
			dp2[i][j]=max(dp2[i][j],dp2[i][j-1]);
		}
	}
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			scanf("%d",&dist[i][j]);
		}
	}
	dijk();
	for(int i=0;i<n/2;i++){
		for(int j=0;j<(1<<i);j++){
			for(int k=0;k<=y;k++){
				for(int l=k;l<=y;l++){
					dp3[j|(1<<i)][l]=max(dp3[j|(1<<i)][l],dp3[j][k]+dp2[i][l-k]);
				}
			}
		}
	}
	for(int i=0;i<(n+1)/2;i++){
		for(int j=0;j<(1<<i);j++){
			for(int k=0;k<=y;k++){
				for(int l=k;l<=y;l++){
					dp4[j|(1<<i)][l]=max(dp4[j|(1<<i)][l],dp4[j][k]+dp2[n/2+i][l-k]);
				}
			}
		}
	}
	for(int i=0;i<(1<<(n/2));i++){
		for(int j=1;j<=y;j++){
			dp3[i][j]=max(dp3[i][j],dp3[i][j-1]);
		}
	}
	for(int i=0;i<(1<<((n+1)/2));i++){
		for(int j=1;j<=y;j++){
			dp4[i][j]=max(dp4[i][j],dp4[i][j-1]);
		}
	}
	int res=0;
	for(int i=0;i<(1<<n);i++){
		int yosan=0;
		int bit1=0;
		int bit2=0;
		for(int bit=n-1;bit>=0;bit--){
			bit1*=2;
			if(bit>=n/2)bit2*=2;
			if(i>>bit & 1){
				if(bit<n/2){
					bit1++;
				}else{
					bit2++;
				}
			}
		}
		for(int j=0;j<n;j++){
			yosan=max(yosan,x-dp[i][j]-dist[j][0]);
		}
		yosan=min(y,yosan);
		for(int j=0;j<=yosan;j++){
			res=max(res,dp3[bit1][j]+dp4[bit2][yosan-j]);
		}
	}
	printf("%d\n",res);
	return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 9068
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;
int N,X,Y;
int dp[1001][1001];
int G[14][14];
int DP[(1<<14)][14];
int mem[(1<<14)][1001];

int main(){
  scanf("%d %d %d",&N,&X,&Y);
  for(int id=0;id<N;id++){
    for(int i=0;i<=Y;i++)dp[id][i]=-1e9;
    dp[id][0]=0;
    int K;
    scanf("%d",&K);
    for(int i=0;i<K;i++){
      int a,b,c;
      scanf("%d %d %d",&a,&b,&c);
      for(int j=0;j<10;j++){
        int na=a*(1<<j);
        int nb=b*(1<<j);
        if(c-(1<<j)<0){
          na=a*c;
          nb=b*c;
          c=0;
        }else{
          c-=(1<<j);
        }
        for(int k=Y;k>=na;k--){
          if(dp[id][k]<dp[id][k-na]+nb){
            dp[id][k]=dp[id][k-na]+nb;
          }
        }
        if(c==0){
          break;
        }
      }
    }

    for(int i=1;i<=Y;i++){
      if(dp[id][i]<dp[id][i-1]){
        dp[id][i]=dp[id][i-1];
      }
    }
  }

  
  for(int i=0;i<N;i++){
    for(int j=0;j<N;j++){
      scanf("%d",&G[i][j]);
    }
  }
  for(int k=0;k<N;k++){
    for(int i=0;i<N;i++){
      for(int j=0;j<N;j++){
        if(G[i][k]+G[k][j]<G[i][j]){
          G[i][j]=G[i][k]+G[k][j];
        }
      }
    }
  }
  
  for(int i=0;i<(1<<N);i++){
    for(int j=0;j<N;j++){
      DP[i][j]=100000000;
    }
  }

  DP[0][0]=0;
  for(int bit=0;bit<(1<<N);bit++){
    for(int pos=0;pos<N;pos++){
      for(int to=0;to<N;to++){
        int nbit=bit|(1<<to);
        int ncost=DP[bit][pos]+G[pos][to];
        if(DP[nbit][to]>ncost){
          DP[nbit][to]=ncost;
        }
      }
    }
  }

  

  mem[0][0]=0;
  for(int i=0;i<=Y;i++)mem[0][i]=-1e9;
  
  int ans=0;
  int tmp[1001];
  
  for(int bit=1;bit<(1<<N);bit++){
    int ny=min(Y,X-DP[bit][0]);

    int dit=bit- (bit&-bit);
    for(int i=0;i<=Y;i++) tmp[i]=mem[dit][i];
    tmp[0]=0;
    
    for(int i=0;i<N;i++){
      if( (bit>>i&1) ){
        for(int j=Y;j>=0;j--){
          int cc;
          cc=0;
          for(int k=0;k<=j;k++){
            cc++;
            if(cc>=100000/Y)break;
            if(tmp[j]<tmp[j-k]+dp[i][k]){
              tmp[j]=tmp[j-k]+dp[i][k];
            }
          }
          cc=0;
          for(int k=j;k>=0;k--){
            cc++;
            if(cc>=20000/Y)break;
            if(tmp[j]<tmp[j-k]+dp[i][k]){
              tmp[j]=tmp[j-k]+dp[i][k];
            }
          }
        }
        break;
      }
    }
    if(ny>=0 && ans<tmp[ny]){
      ans=tmp[ny];
    }
    for(int i=0;i<=Y;i++) mem[bit][i]=tmp[i];
  }
  
  printf("%d\n",ans);
  return 0;
}
accuracy: 1
time_ms: 1880
memory_kb: 68144
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;
int N,X,Y;
int dp[1001][1001];
int G[14][14];
int DP[(1<<14)][14];
int mem[(1<<14)][1001];

int main(){
  scanf("%d %d %d",&N,&X,&Y);
  for(int id=0;id<N;id++){
    for(int i=0;i<=Y;i++)dp[id][i]=-1e9;
    dp[id][0]=0;
    int K;
    scanf("%d",&K);
    for(int i=0;i<K;i++){
      int a,b,c;
      scanf("%d %d %d",&a,&b,&c);
      for(int j=0;j<10;j++){
        int na=a*(1<<j);
        int nb=b*(1<<j);
        if(c-(1<<j)<0){
          na=a*c;
          nb=b*c;
          c=0;
        }else{
          c-=(1<<j);
        }
        for(int k=Y;k>=na;k--){
          if(dp[id][k]<dp[id][k-na]+nb){
            dp[id][k]=dp[id][k-na]+nb;
          }
        }
        if(c==0){
          break;
        }
      }
    }

    for(int i=1;i<=Y;i++){
      if(dp[id][i]<dp[id][i-1]){
        dp[id][i]=dp[id][i-1];
      }
    }
  }

  
  for(int i=0;i<N;i++){
    for(int j=0;j<N;j++){
      scanf("%d",&G[i][j]);
    }
  }
  for(int k=0;k<N;k++){
    for(int i=0;i<N;i++){
      for(int j=0;j<N;j++){
        if(G[i][k]+G[k][j]<G[i][j]){
          G[i][j]=G[i][k]+G[k][j];
        }
      }
    }
  }
  
  for(int i=0;i<(1<<N);i++){
    for(int j=0;j<N;j++){
      DP[i][j]=100000000;
    }
  }

  DP[0][0]=0;
  for(int bit=0;bit<(1<<N);bit++){
    for(int pos=0;pos<N;pos++){
      for(int to=0;to<N;to++){
        int nbit=bit|(1<<to);
        int ncost=DP[bit][pos]+G[pos][to];
        if(DP[nbit][to]>ncost){
          DP[nbit][to]=ncost;
        }
      }
    }
  }

  

  mem[0][0]=0;
  for(int i=0;i<=Y;i++)mem[0][i]=-1e9;
  
  int ans=0;
  int tmp[1001];
  
  for(int bit=1;bit<(1<<N);bit++){
    int ny=min(Y,X-DP[bit][0]);

    int dit=bit- (bit&-bit);
    for(int i=0;i<=Y;i++) tmp[i]=mem[dit][i];
    tmp[0]=0;
    
    for(int i=0;i<N;i++){
      if( (bit>>i&1) ){
        for(int j=Y;j>=0;j--){
          int cc;
          cc=0;
          for(int k=0;k<=j;k++){
            cc++;
            if(cc>=20000/Y)break;
            if(tmp[j]<tmp[j-k]+dp[i][k]){
              tmp[j]=tmp[j-k]+dp[i][k];
            }
          }
          cc=0;
          for(int k=j;k>=0;k--){
            cc++;
            if(cc>=100000/Y)break;
            if(tmp[j]<tmp[j-k]+dp[i][k]){
              tmp[j]=tmp[j-k]+dp[i][k];
            }
          }
        }
        break;
      }
    }
    if(ny>=0 && ans<tmp[ny]){
      ans=tmp[ny];
    }
    for(int i=0;i<=Y;i++) mem[bit][i]=tmp[i];
  }
  
  printf("%d\n",ans);
  return 0;
}
accuracy: 0.8222222222222222
time_ms: 800
memory_kb: 35700
final_rank: 19

code_snippet: #include<bits/stdc++.h>
using namespace std;
int N,X,Y;
int dp[1001][1001];
int G[14][14];
int DP[(1<<14)][14];
int mem[(1<<14)][1001];

int main(){
  scanf("%d %d %d",&N,&X,&Y);
  for(int id=0;id<N;id++){
    for(int i=0;i<=Y;i++)dp[id][i]=-1e9;
    dp[id][0]=0;
    int K;
    scanf("%d",&K);
    for(int i=0;i<K;i++){
      int a,b,c;
      scanf("%d %d %d",&a,&b,&c);
      for(int j=0;j<10;j++){
        int na=a*(1<<j);
        int nb=b*(1<<j);
        if(c-(1<<j)<0){
          na=a*c;
          nb=b*c;
          c=0;
        }else{
          c-=(1<<j);
        }
        for(int k=Y;k>=na;k--){
          if(dp[id][k]<dp[id][k-na]+nb){
            dp[id][k]=dp[id][k-na]+nb;
          }
        }
        if(c==0){
          break;
        }
      }
    }

    for(int i=1;i<=Y;i++){
      if(dp[id][i]<dp[id][i-1]){
        dp[id][i]=dp[id][i-1];
      }
    }
  }

  
  for(int i=0;i<N;i++){
    for(int j=0;j<N;j++){
      scanf("%d",&G[i][j]);
    }
  }
  for(int k=0;k<N;k++){
    for(int i=0;i<N;i++){
      for(int j=0;j<N;j++){
        if(G[i][k]+G[k][j]<G[i][j]){
          G[i][j]=G[i][k]+G[k][j];
        }
      }
    }
  }
  
  for(int i=0;i<(1<<N);i++){
    for(int j=0;j<N;j++){
      DP[i][j]=100000000;
    }
  }

  DP[0][0]=0;
  for(int bit=0;bit<(1<<N);bit++){
    for(int pos=0;pos<N;pos++){
      for(int to=0;to<N;to++){
        int nbit=bit|(1<<to);
        int ncost=DP[bit][pos]+G[pos][to];
        if(DP[nbit][to]>ncost){
          DP[nbit][to]=ncost;
        }
      }
    }
  }

  

  mem[0][0]=0;
  for(int i=0;i<=Y;i++)mem[0][i]=-1e9;
  
  int ans=0;
  int tmp[1001];
  
  for(int bit=1;bit<(1<<N);bit++){
    int ny=min(Y,X-DP[bit][0]);

    int dit=bit- (bit&-bit);
    for(int i=0;i<=Y;i++) tmp[i]=mem[dit][i];
    tmp[0]=0;
    
    for(int i=0;i<N;i++){
      if( (bit>>i&1) ){
        for(int j=Y;j>=0;j--){
          int cc;
          cc=0;
          for(int k=0;k<=j;k++){
            cc++;
            if(cc>=70000/Y)break;
            if(tmp[j]<tmp[j-k]+dp[i][k]){
              tmp[j]=tmp[j-k]+dp[i][k];
            }
          }
          cc=0;
          for(int k=j;k>=0;k--){
            cc++;
            if(cc>=70000/Y)break;
            if(tmp[j]<tmp[j-k]+dp[i][k]){
              tmp[j]=tmp[j-k]+dp[i][k];
            }
          }
        }
        break;
      }
    }
    if(ny>=0 && ans<tmp[ny]){
      ans=tmp[ny];
    }
    for(int i=0;i<=Y;i++) mem[bit][i]=tmp[i];
  }
  
  printf("%d\n",ans);
  return 0;
}
accuracy: 0.8222222222222222
time_ms: 920
memory_kb: 35700
final_rank: 20

code_snippet: #include<bits/stdc++.h>
using namespace std;
int N,X,Y;
int dp[1001][1001];
int G[14][14];
int DP[(1<<14)][14];
int mem[(1<<14)][1001];

int main(){
  scanf("%d %d %d",&N,&X,&Y);
  for(int id=0;id<N;id++){
    for(int i=0;i<=Y;i++)dp[id][i]=-1e9;
    dp[id][0]=0;
    int K;
    scanf("%d",&K);
    for(int i=0;i<K;i++){
      int a,b,c;
      scanf("%d %d %d",&a,&b,&c);
      for(int j=0;j<10;j++){
        int na=a*(1<<j);
        int nb=b*(1<<j);
        if(c-(1<<j)<0){
          na=a*c;
          nb=b*c;
          c=0;
        }else{
          c-=(1<<j);
        }
        for(int k=Y;k>=na;k--){
          if(dp[id][k]<dp[id][k-na]+nb){
            dp[id][k]=dp[id][k-na]+nb;
          }
        }
        if(c==0){
          break;
        }
      }
    }

    for(int i=1;i<=Y;i++){
      if(dp[id][i]<dp[id][i-1]){
        dp[id][i]=dp[id][i-1];
      }
    }
  }

  
  for(int i=0;i<N;i++){
    for(int j=0;j<N;j++){
      scanf("%d",&G[i][j]);
    }
  }
  for(int k=0;k<N;k++){
    for(int i=0;i<N;i++){
      for(int j=0;j<N;j++){
        if(G[i][k]+G[k][j]<G[i][j]){
          G[i][j]=G[i][k]+G[k][j];
        }
      }
    }
  }
  
  for(int i=0;i<(1<<N);i++){
    for(int j=0;j<N;j++){
      DP[i][j]=100000000;
    }
  }

  DP[0][0]=0;
  for(int bit=0;bit<(1<<N);bit++){
    for(int pos=0;pos<N;pos++){
      for(int to=0;to<N;to++){
        int nbit=bit|(1<<to);
        int ncost=DP[bit][pos]+G[pos][to];
        if(DP[nbit][to]>ncost){
          DP[nbit][to]=ncost;
        }
      }
    }
  }

  

  mem[0][0]=0;
  for(int i=0;i<=Y;i++)mem[0][i]=-1e9;
  
  int ans=0;
  int tmp[1001];
  
  for(int bit=1;bit<(1<<N);bit++){
    int ny=min(Y,X-DP[bit][0]);

    int dit=bit- (bit&-bit);
    for(int i=0;i<=Y;i++) tmp[i]=mem[dit][i];
    tmp[0]=0;
    
    for(int i=0;i<N;i++){
      if( (bit>>i&1) ){
        for(int j=Y;j>=0;j--){
          int cc;
          cc=0;
          for(int k=0;k<=j;k++){
            cc++;
            if(cc>=20000/Y)break;
            if(tmp[j]<tmp[j-k]+dp[i][k]){
              tmp[j]=tmp[j-k]+dp[i][k];
            }
          }
          cc=0;
          for(int k=j;k>=0;k--){
            cc++;
            if(cc>=20000/Y)break;
            if(tmp[j]<tmp[j-k]+dp[i][k]){
              tmp[j]=tmp[j-k]+dp[i][k];
            }
          }
        }
        break;
      }
    }
    if(ny>=0 && ans<tmp[ny]){
      ans=tmp[ny];
    }
    for(int i=0;i<=Y;i++) mem[bit][i]=tmp[i];
  }
  
  printf("%d\n",ans);
  return 0;
}
accuracy: 0.8222222222222222
time_ms: 320
memory_kb: 35700
final_rank: 17

code_snippet: #include<bits/stdc++.h>
using namespace std;
int N,X,Y;
int dp[1001][1001];
int G[14][14];
int DP[(1<<14)][14];

int main(){
  scanf("%d %d %d",&N,&X,&Y);
  for(int id=0;id<N;id++){
    for(int i=0;i<=Y;i++)dp[id][i]=-1e9;
    dp[id][0]=0;
    int K;
    scanf("%d",&K);
    for(int i=0;i<K;i++){
      int a,b,c;
      scanf("%d %d %d",&a,&b,&c);
      for(int j=0;j<10;j++){
        int na=a*(1<<j);
        int nb=b*(1<<j);
        if(c-(1<<j)<0){
          na=a*c;
          nb=b*c;
          c=0;
        }else{
          c-=(1<<j);
        }
        for(int k=Y;k>=na;k--){
          if(dp[id][k]<dp[id][k-na]+nb){
            dp[id][k]=dp[id][k-na]+nb;
          }
        }
        if(c==0){
          break;
        }
      }
    }

    for(int i=1;i<=Y;i++){
      if(dp[id][i]<dp[id][i-1]){
        dp[id][i]=dp[id][i-1];
      }
    }
  }

  
  for(int i=0;i<N;i++){
    for(int j=0;j<N;j++){
      scanf("%d",&G[i][j]);
    }
  }
  for(int k=0;k<N;k++){
    for(int i=0;i<N;i++){
      for(int j=0;j<N;j++){
        if(G[i][k]+G[k][j]<G[i][j]){
          G[i][j]=G[i][k]+G[k][j];
        }
      }
    }
  }
  
  for(int i=0;i<(1<<N);i++){
    for(int j=0;j<N;j++){
      DP[i][j]=100000000;
    }
  }

  DP[0][0]=0;
  for(int bit=0;bit<(1<<N);bit++){
    for(int pos=0;pos<N;pos++){
      for(int to=0;to<N;to++){
        int nbit=bit|(1<<to);
        int ncost=DP[bit][pos]+G[pos][to];
        if(DP[nbit][to]>ncost){
          DP[nbit][to]=ncost;
        }
      }
    }
  }

  
  
  int ans=0;
  int tmp[1001];
  for(int bit=0;bit<(1<<N);bit++){
    int ny=min(Y,X-DP[bit][0]);
    if(ny<0)continue;

    for(int i=0;i<=ny;i++)tmp[i]=-1e9;
    tmp[0]=0;
    
    for(int i=0;i<N;i++){
      if( (bit>>i&1) ){


        
        for(int j=ny;j>=1;j--){
          int xx=10000/j;
          int cc=0;
          for(int k=0;k<=j;k++){
            cc++;
            if(cc>=xx)break;
            if(tmp[j]<tmp[j-k]+dp[i][k]){
              tmp[j]=tmp[j-k]+dp[i][k];
            }
          }
          
          cc=0;
          for(int k=j;k>=0;k--){
            cc++;
            if(cc>=xx)break;
            if(tmp[j]<tmp[j-k]+dp[i][k]){
              tmp[j]=tmp[j-k]+dp[i][k];
            }
          }
          
        }
        
      }
    }
    if(ans<tmp[ny]){
      ans=tmp[ny];
    }

  }
  
  printf("%d\n",ans);
  return 0;
}
accuracy: 0.8222222222222222
time_ms: 1670
memory_kb: 3644
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
int N,X,Y;
int dp[1001][1001];
int G[14][14];
int DP[(1<<14)][14];

int main(){
  scanf("%d %d %d",&N,&X,&Y);
  for(int id=0;id<N;id++){
    for(int i=0;i<=Y;i++)dp[id][i]=-1e9;
    dp[id][0]=0;
    int K;
    scanf("%d",&K);
    for(int i=0;i<K;i++){
      int a,b,c;
      scanf("%d %d %d",&a,&b,&c);
      for(int j=0;j<10;j++){
        int na=a*(1<<j);
        int nb=b*(1<<j);
        if(c-(1<<j)<0){
          na=a*c;
          nb=b*c;
          c=0;
        }else{
          c-=(1<<j);
        }
        for(int k=Y;k>=na;k--){
          if(dp[id][k]<dp[id][k-na]+nb){
            dp[id][k]=dp[id][k-na]+nb;
          }
        }
        if(c==0){
          break;
        }
      }
    }

    for(int i=1;i<=Y;i++){
      if(dp[id][i]<dp[id][i-1]){
        dp[id][i]=dp[id][i-1];
      }
    }
  }

  
  for(int i=0;i<N;i++){
    for(int j=0;j<N;j++){
      scanf("%d",&G[i][j]);
    }
  }
  for(int k=0;k<N;k++){
    for(int i=0;i<N;i++){
      for(int j=0;j<N;j++){
        if(G[i][k]+G[k][j]<G[i][j]){
          G[i][j]=G[i][k]+G[k][j];
        }
      }
    }
  }
  
  for(int i=0;i<(1<<N);i++){
    for(int j=0;j<N;j++){
      DP[i][j]=100000000;
    }
  }

  DP[0][0]=0;
  for(int bit=0;bit<(1<<N);bit++){
    for(int pos=0;pos<N;pos++){
      for(int to=0;to<N;to++){
        int nbit=bit|(1<<to);
        int ncost=DP[bit][pos]+G[pos][to];
        if(DP[nbit][to]>ncost){
          DP[nbit][to]=ncost;
        }
      }
    }
  }

  
  
  int ans=0;
  int tmp[1001];
  for(int bit=0;bit<(1<<N);bit++){
    int ny=min(Y,X-DP[bit][0]);
    if(ny<0)continue;

    for(int i=0;i<=ny;i++)tmp[i]=-1e9;
    tmp[0]=0;
    
    for(int i=0;i<N;i++){
      if( (bit>>i&1) ){

        int xx=10000/ny;
        
        for(int j=ny;j>=0;j--){
          int cc=0;
          for(int k=0;k<=j;k++){
            cc++;
            if(cc>=xx)break;
            if(tmp[j]<tmp[j-k]+dp[i][k]){
              tmp[j]=tmp[j-k]+dp[i][k];
            }
          }
          
          cc=0;
          for(int k=j;k>=0;k--){
            cc++;
            if(cc>=xx)break;
            if(tmp[j]<tmp[j-k]+dp[i][k]){
              tmp[j]=tmp[j-k]+dp[i][k];
            }
          }
          
        }
        
      }
    }
    if(ans<tmp[ny]){
      ans=tmp[ny];
    }

  }
  
  printf("%d\n",ans);
  return 0;
}
accuracy: 0.8222222222222222
time_ms: 490
memory_kb: 3668
final_rank: 16

code_snippet: #include <bits/stdc++.h>
 
using namespace std;
 
const int INF = 1 << 29;
 
int N, X, Y, G[14][14];
int tsp[1 << 14][14];
vector< tuple< int, int, int > > vs[14];
int dp1[1 << 7][1001];
int dp2[1 << 7][1001];
 
int main()
{
 
  cin >> N >> X >> Y;
  for(int i = 0; i < N; i++) {
    int K;
    cin >> K;
    for(int j = 0; j < K; j++) {
      int a, b, c;
      cin >> a >> b >> c;
      vs[i].emplace_back(a, b, c);
    }
  }
  for(int i = 0; i < N; i++) {
    for(int j = 0; j < N; j++) {
      cin >> G[i][j];
    }
  }
 
 
  fill_n(*tsp, (1 << 14) * 14, INF);
  for(int i = 0; i < N; i++) tsp[1 << i][i] = G[0][i];
  for(int i = 0; i < (1 << N); i++) {
    for(int j = 0; j < N; j++) {
      for(int k = 0; k < N; k++) {
        tsp[i | (1 << k)][k] = min(tsp[i | (1 << k)][k], tsp[i][j] + G[j][k]);
      }
    }
  }
 
  vector< int > st1, st2;
  int mid = N / 2;
  for(int i = 0; i < (1 << mid); i++) st1.emplace_back(i);
  for(int i = 0; i < (1 << (N - mid)); i++) st2.emplace_back(i);
 
  for(int i = 0; i < mid; i++) {
    for(auto &p : vs[i]) {
      int a, b, c;
      tie(a, b, c) = p;
      for(int k = 0; c > 0; k++) {
        int key = min(c, (int) (1 << k));
        c -= key;
        for(int j = 1000; j >= key * a; j--) {
          dp1[1 << i][j] = max(dp1[1 << i][j], dp1[1 << i][j - key * a] + key * b);
        }
      }
    }
 
    for(int j = 1; j <= 1000; j++) {
      dp1[1 << i][j] = max(dp1[1 << i][j], dp1[1 << i][j - 1]);
    }
  }
 
  for(int i = 0; i < N - mid; i++) {
    for(auto &p : vs[i + mid]) {
      int a, b, c;
      tie(a, b, c) = p;
      for(int k = 0; c > 0; k++) {
        int key = min(c, (int) (1 << k));
        c -= key;
        for(int j = 1000; j >= key * a; j--) {
          dp2[1 << i][j] = max(dp2[1 << i][j], dp2[1 << i][j - key * a] + key * b);
        }
      }
    }
 
    for(int j = 1; j <= 1000; j++) {
      dp2[1 << i][j] = max(dp2[1 << i][j], dp2[1 << i][j - 1]);
    }
  }
 
  sort(begin(st1), end(st1), [&](int a, int b)
  {
    return (__builtin_popcount(a) < __builtin_popcount(b));
  });
  sort(begin(st2), end(st2), [&](int a, int b)
  {
    return (__builtin_popcount(a) < __builtin_popcount(b));
  });
 
  for(auto &i : st1) {
 
    if(__builtin_popcount(i) > 1) {
      int idx = -1;
      for(int j = 0; j < mid; j++) {
        if((i >> j) & 1) {
          idx = j;
          break;
        }
      }
 
      int bit = i ^(1 << idx);
 
      for(int j = 0; j <= 1000; j++) {
        dp1[i][j] = dp1[bit][j];
      }
 
      for(auto &p : vs[idx]) {
        int a, b, c;
        tie(a, b, c) = p;
        for(int k = 0; c > 0; k++) {
          int key = min(c, (int) (1 << k));
          c -= key;
          for(int j = 1000; j >= key * a; j--) {
            dp1[i][j] = max(dp1[i][j], dp1[i][j - key * a] + key * b);
          }
        }
      }
      for(int j = 1; j <= 1000; j++) {
        dp1[i][j] = max(dp1[i][j], dp1[i][j - 1]);
      }
    }
  }
 
  for(auto &i : st2) {
 
    if(__builtin_popcount(i) > 1) {
      int idx = -1;
      for(int j = 0; j < N - mid; j++) {
        if((i >> j) & 1) {
          idx = j;
          break;
        }
      }
 
      int bit = i ^(1 << idx);
 
      for(int j = 0; j <= 1000; j++) {
        dp2[i][j] = dp2[bit][j];
      }
 
      for(auto &p : vs[idx + mid]) {
        int a, b, c;
        tie(a, b, c) = p;
        for(int k = 0; c > 0; k++) {
          int key = min(c, (int) (1 << k));
          c -= key;
          for(int j = 1000; j >= key * a; j--) {
            dp2[i][j] = max(dp2[i][j], dp2[i][j - key * a] + key * b);
          }
        }
      }
      for(int j = 1; j <= 1000; j++) {
        dp2[i][j] = max(dp2[i][j], dp2[i][j - 1]);
 
      }
    }
 
  }
 
  int ret = 0;
  for(auto &s : st1) {
    for(auto &t : st2) {
      int bit = (t << mid) | s;
      int rest = X - tsp[bit][0];
      if(rest < 0) continue;
      int cost = min(rest, Y);
      for(int i = 0; i <= cost; i++) {
        ret = max(ret, dp1[s][i] + dp2[t][cost - i]);
      }
    }
  }
 
 
  cout << ret << endl;
}
accuracy: 1
time_ms: 850
memory_kb: 5036
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define F first
#define S second
typedef pair<int,int> P;
typedef pair<int,P> PP;
const int N=14;
int dp1[N][1001],c[N][N],dp2[1<<N][N],dp3[2][1<<(N/2+1)][1001],dp[1<<N][1001],ans;
vector<PP> a[N+1];
int main() {
  int A,B,n;
  cin >> n >> A >> B;
  for(int k=0; k<n; k++) {
    fill(dp1[k],dp1[k]+B+1,-(1<<30));
    dp1[k][0]=0;
    int m;
    cin >> m;
    for(int i=0; i<m; i++) {
      PP p;
      cin >> p.S.F >> p.F >> p.S.S;
      int t=1;
      while(p.S.S) {
        do {
          for(int j=B; j>=0; j--) {
            if(j+p.S.F*t<=B) dp1[k][j+p.S.F*t]=max(dp1[k][j+p.S.F*t],dp1[k][j]+p.F*t);
          }
          p.S.S-=t;
        } while(p.S.S%(t*2));
        t*=2;
      }
    }
    for(int i=0; i<B; i++) dp1[k][i+1]=max(dp1[k][i+1],dp1[k][i]);
  }
  for(int i=0; i<n; i++)for(int j=0; j<n; j++) cin >> c[i][j];
  for(int k=0;k<n;k++)for(int i=0;i<n;i++)for(int j=0;j<n;j++)c[i][j]=min(c[i][j],c[i][k]+c[k][j]);
  for(int t=0;t<(1<<n);t++)for(int i=0;i<n;i++) dp2[t][i]=1<<30;
  for(int i=0; i<n; i++) dp2[1<<i][i]=c[0][i];
  for(int t=1; t<(1<<n); t++) {
    for(int i=0; i<n; i++) {
      if(!(t&(1<<i))) continue;
      for(int j=0; j<n; j++) {
        if(t&(1<<j)) continue;
        dp2[t|(1<<j)][j]=min(dp2[t|(1<<j)][j],dp2[t][i]+c[i][j]);
      }
    }
  }
  for(int t=0;t<(1<<(n/2+n%2));t++)for(int i=0;i<=B;i++)dp3[0][t][i]=dp3[1][t][i]=-(1<<30);
  for(int l=0; l<2; l++) {
    dp3[l][0][0]=0;
    for(int t=0; t<(1<<(n/2+n%2*l)); t++) {
      for(int i=0; i<n/2+n%2*l; i++) {
        if(t&(1<<i)) continue;
        for(int j=B; j>=0; j--) {
          for(int k=B-j; k>=0; k--) {
            dp3[l][t|(1<<i)][j+k]=max(dp3[l][t|(1<<i)][j+k],dp3[l][t][j]+dp1[i+n/2*l][k]);
          }
        }
      }
      for(int i=0; i<B; i++) dp3[l][t][i+1]=max(dp3[l][t][i+1],dp3[l][t][i]);
    }
  }
  for(int t=0;t<(1<<n);t++)for(int i=0;i<=B;i++)dp[t][i]=-(1<<30);
  for(int t=0;t<(1<<(n/2));t++) {
    if(n>1&&t%2==0) continue;
    for(int s=0; s<(1<<(n/2+n%2)); s++) {
      int C=max(0,A-dp2[t|(s<<(n/2))][0]),D=min(B,C);
      for(int i=0; i<=D; i++)ans=max(ans,dp3[0][t][i]+dp3[1][s][D-i]);
    }
  }
  cout << ans << endl;
  return 0;
}
accuracy: 1
time_ms: 530
memory_kb: 69076
final_rank: 14