Problem:
Problem E: アニペロ
猛暑が続いた、長かったようで短かったような夏がもうすぐ終わろうとしていた。
そんな8月下旬のある日、とある2D好きな人物とその先輩のslipは、アニペロサマーライブ、通称アニペロと呼ばれるイベントに参加していた。
アニペロとは、さまざまなアニメソングアーティストたちが集結する、日本国内最大のアニメソングライブイベントである。
今年のアニペロは、公式で公表されていたアーティストの他に、シークレットで超豪華歌手も出演し、大盛況の内に幕を閉じた。
アニペロには初参戦だった2D好きな彼は、ライブ後の余韻にひたりつつも、ひとつの疑問を抱えていた。
「アニペロに出演するアーティストはどのように決めているのだろうか？」
彼は、数あるアーティストの中から、出演アーティストの選出をするのに、次のような方法があるのではないかと、選出法を考えてみた。
まず、アニペロのアーティストには、シークレットアーティストとスタンダードアーティストの2種類の分類があるものとする。
シークレットアーティストとは、ライブに出演することを事前公表せず、ライブ本番になって突然現れるアーティストのことを指す。
スタンダードアーティストとは、ライブに出演することを事前に公表してよいアーティストのことを指す。
全てのアーティストは、次のステータスを持つ。
アーティスト名：文字列
アーティストを雇うための金額（以下、雇用金と呼ぶ）：自然数
このアーティストが出演することで、お客をどれほど満足させられるか（以下、満足度と呼ぶ）：自然数
今回、ライブに出演するアーティストを選ぶために、シークレットアーティスト候補
N
人、スタンダードアーティスト候補
M
人が、すでに用意されているものとする。さらに、ライブの主催者は、アーティストを雇用するために使用できる資金
LIMIT
を持っているものとする。
主催者は、次の条件を満たすように、アーティストを選出しなければならない。
N
人のシークレットアーティスト枠から、1人以上、2人以下を選出する(1人or2人なのは、シークレットがいなかったり多かったりすることを避けるためである)
M
人のスタンダードアーティスト枠から、
X
人以上のアーティストを選出する
アーティストを全て選出し終えたとき、雇用金の合計を、
LIMIT
以下にする
選出したアーティスト全員で得られる満足度の合計を最大化する
さて、ここまで選出法を考えた2D好きな彼は、この方法でプログラムを書いてみようと思った。しかし、彼は選出法を考えるのに気力を使ってしまい、プログラムを書く気力がなくなってしまったようなので、彼の代わりにプログラムを書いてあげてほしい。
あなたの仕事は、上記の選出法に従い、アーティストを選出したときのお客の最大満足度を出力するプログラムを作成することである。
Input
入力は、複数のデータセットからなる。データセットの総数は20以下である。
各データセットは、次の形をしている。
LIMIT
N
M
X
SEC_NAME
1
SEC_E
1
SEC_S
1
...
SEC_NAME
i
SEC_E
i
SEC_S
i
...
SEC_NAME
N
SEC_E
N
SEC_S
N
NAME
1
E
1
S
1
...
NAME
i
E
i
S
i
...
NAME
M
E
M
S
M
整数
LIMIT
(
4 ≤
LIMIT
≤ 1000
)、
N
(
2 ≤ N ≤ 100
)、
M
(
2 ≤ M ≤ 100
)、
X
(
2 ≤ X ≤ M
)は、
それぞれアーティストを雇用するのに使用できる資金、シークレットアーティスト候補の数、スタンダードアーティスト候補の数、スタンダードアーティストから選出しなければならない最低人数を表す。
SEC_NAME
i
、
NAME
i
、はそれぞれシークレットアーティスト候補、スタンダードアーティスト候補の名前を指す30文字以下の文字列である。
文字列には、アルファベット('A'-'Z', 'a'-'z')のみが使用される。
同じアーティスト名が2回以上出現することはない。
整数
SEC_E
i
、
E
i
(
1 ≤
SEC_E
i
,
E
i
≤ 10
)、
SEC_S
i
、
S
i
(
1 ≤
SEC_S
i
,
S
i
≤ 10
) は、それぞれシークレットアーティスト候補の雇用金、スタンダードアーティスト候補の雇用金、シークレットアーティスト候補が出演したときに得られる満足度、スタンダードアーティスト候補が出演したときに得られる満足度を表す。
入力の終了は、0が4つの行で示される。このデータについては処理する必要はない。
Output
選出法を適用してアーティストを選出したとき、お客の満足度の最大値を出力せよ。
アーティストの選出の仕方は、必ずあると仮定してよい。
Sample Input
100 2 2 2
A 5 6
B 7 8
C 1 2
D 3 4
27 2 3 3
A 8 10
B 8 10
C 6 7
D 5 4
E 8 9
27 2 3 2
A 8 10
B 8 10
C 6 7
D 5 4
E 8 9
44 3 6 5
YamatoNoHito 9 10
ZettoNoHito 9 10
TMR 10 10
SkillNoGroup 8 10
NanaSama 6 9
FRPSD 6 8
Magi3rdDeshi 5 7
Magi13thDeshi 2 2
MagicalItoh 4 6
0 0 0 0
Output for Sample Input
20
30
31
55

Submitted solutions:

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

int limit, n, m, x;
int e1[N], s1[N];
int e2[N], s2[N];
int dp[1010][N][N];
int ep[1010];

int main(){
	while (1){
		cin >> limit >> n >> m >> x;
		if (limit == 0 && n == 0 && m == 0 && x == 0) break;
		string name;
		for (int i = 1; i <= n; i++) cin >> name >> e1[i] >> s1[i];
		for (int i = 1; i <= m; i++) cin >> name >> e2[i] >> s2[i];
		for (int i = 0; i <= 1000; i++){
			for (int j = 0; j <= m; j++){
				for (int k = 0; k <= m; k++) dp[i][j][k] = -1e9;
			}
		}
		for (int i = 0; i <= 1000; i++) {
			for (int j = 0; j <= m; j++) dp[i][j][0] = 0;
		}
		for (int i = 1; i <= 1000; i++){
			for (int j = 1; j <= m; j++){
				for (int k = 1; k <= j; k++){
					dp[i][j][k] = dp[i][j - 1][k];
					if (i >= e2[j]) dp[i][j][k] = max(dp[i][j][k], dp[i - e2[j]][j - 1][k - 1] + s2[j]);
				}
			}
		}
		for (int i = 1; i <= 1000; i++){
			ep[i] = 0;
			for (int k = x; k <= m; k++) ep[i] = max(ep[i], dp[i][m][k]);
		}
		int ans = 0;
		for (int i = 1; i <= n; i++) {
			if (limit >= e1[i]) ans = max(ans, s1[i] + ep[limit - e1[i]]);
		}
		for (int i = 1; i <= n; i++){
			for (int j = i + 1; j <= n; j++){
				if (limit >= e1[i] + e1[j]) ans = max(ans, s1[i] + s1[j] + ep[limit - e1[i] - e1[j]]);
			}
		}
		cout << ans << endl;
	}
	
}
accuracy: 1
time_ms: 30
memory_kb: 50680
final_rank: 17

code_snippet: #line 2 "/home/yuruhiya/programming/library/template/template.cpp"
#include <bits/stdc++.h>
#line 4 "/home/yuruhiya/programming/library/template/constants.cpp"
#include <string_view>
#line 7 "/home/yuruhiya/programming/library/template/constants.cpp"

#define rep(i, n) for (int i = 0; i < (n); ++i)
#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define rrep(i, n) for (int i = (n)-1; i >= 0; --i)
#define rfor(i, m, n) for (int i = (m); i >= (n); --i)
#define unless(c) if (!(c))
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define range_it(a, l, r) (a).begin() + (l), (a).begin() + (r)

using namespace std;
using ll = long long;
using LD = long double;
using VB = vector<bool>;
using VVB = vector<VB>;
using VI = vector<int>;
using VVI = vector<VI>;
using VL = vector<ll>;
using VVL = vector<VL>;
using VS = vector<string>;
using VD = vector<LD>;
using PII = pair<int, int>;
using VP = vector<PII>;
using PLL = pair<ll, ll>;
using VPL = vector<PLL>;
template <class T> using PQ = priority_queue<T>;
template <class T> using PQS = priority_queue<T, vector<T>, greater<T>>;
constexpr int inf = 1000000000;
constexpr long long inf_ll = 1000000000000000000ll, MOD = 1000000007;
constexpr long double PI = 3.14159265358979323846, EPS = 1e-12;
namespace CharacterClass {
	constexpr string_view
	    digit = "0123456789",
	    xdigit = "0123456789ABCDEFabcdef", lower = "abcdefghijklmnopqrstuvwxyz",
	    upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
	    alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
	    alnum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
	    word = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz",
	    punct = R"(!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)",
	    graph =
	        R"(!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~)",
	    print =
	        R"( !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~)",
	    blank = " \t", space = " \t\n\r\f\v";
}  // namespace CharacterClass
#line 7 "/home/yuruhiya/programming/library/template/Input.cpp"
using namespace std;

#ifdef _WIN32
#define getchar_unlocked _getchar_nolock
#define putchar_unlocked _putchar_nolock
#define fwrite_unlocked fwrite
#define fflush_unlocked fflush
#endif
class Scanner {
	static int gc() {
		return getchar_unlocked();
	}
	static char next_char() {
		char c;
		read(c);
		return c;
	}
	template <class T> static void read(T& v) {
		cin >> v;
	}
	static void read(char& v) {
		while (isspace(v = gc()))
			;
	}
	static void read(bool& v) {
		v = next_char() != '0';
	}
	static void read(string& v) {
		v.clear();
		for (char c = next_char(); !isspace(c); c = gc()) v += c;
	}
	static void read(int& v) {
		v = 0;
		bool neg = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void read(long long& v) {
		v = 0;
		bool neg = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c); c = gc()) v = v * 10 + (c - '0');
		if (neg) v = -v;
	}
	static void read(double& v) {
		v = 0;
		double dp = 1;
		bool neg = false, after_dp = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.') {
				after_dp = true;
			} else if (after_dp) {
				v += (c - '0') * (dp *= 0.1);
			} else {
				v = v * 10 + (c - '0');
			}
		}
		if (neg) v = -v;
	}
	static void read(long double& v) {
		v = 0;
		long double dp = 1;
		bool neg = false, after_dp = false;
		char c = next_char();
		if (c == '-') {
			neg = true;
			c = gc();
		}
		for (; isdigit(c) || c == '.'; c = gc()) {
			if (c == '.') {
				after_dp = true;
			} else if (after_dp) {
				v += (c - '0') * (dp *= 0.1);
			} else {
				v = v * 10 + (c - '0');
			}
		}
		if (neg) v = -v;
	}
	template <class T, class U> static void read(pair<T, U>& v) {
		read(v.first);
		read(v.second);
	}
	template <class T> static void read(vector<T>& v) {
		for (auto& e : v) read(e);
	}
	template <size_t N = 0, class T> static void read_tuple_impl(T& v) {
		if constexpr (N < tuple_size_v<T>) {
			read(get<N>(v));
			read_tuple_impl<N + 1>(v);
		}
	}
	template <class... T> static void read(tuple<T...>& v) {
		read_tuple_impl(v);
	}
	struct ReadVectorHelper {
		size_t n;
		ReadVectorHelper(size_t _n) : n(_n) {}
		template <class T> operator vector<T>() {
			vector<T> v(n);
			read(v);
			return v;
		}
	};
	struct Read2DVectorHelper {
		size_t n, m;
		Read2DVectorHelper(const pair<size_t, size_t>& nm) : n(nm.first), m(nm.second) {}
		template <class T> operator vector<vector<T>>() {
			vector<vector<T>> v(n, vector<T>(m));
			read(v);
			return v;
		}
	};

public:
	string read_line() const {
		string v;
		for (char c = gc(); c != '\n' && c != '\0'; c = gc()) v += c;
		return v;
	}
	template <class T> T read() const {
		T v;
		read(v);
		return v;
	}
	template <class T> vector<T> read_vector(size_t n) const {
		vector<T> a(n);
		read(a);
		return a;
	}
	template <class T> operator T() const {
		return read<T>();
	}
	int operator--(int) const {
		return read<int>() - 1;
	}
	ReadVectorHelper operator[](size_t n) const {
		return ReadVectorHelper(n);
	}
	Read2DVectorHelper operator[](const pair<size_t, size_t>& nm) const {
		return Read2DVectorHelper(nm);
	}
	void operator()() const {}
	template <class H, class... T> void operator()(H&& h, T&&... t) const {
		read(h);
		operator()(forward<T>(t)...);
	}

private:
	template <template <class...> class, class...> struct Multiple;
	template <template <class...> class V, class Head, class... Tail>
	struct Multiple<V, Head, Tail...> {
		template <class... Args> using vec = V<vector<Head>, Args...>;
		using type = typename Multiple<vec, Tail...>::type;
	};
	template <template <class...> class V> struct Multiple<V> { using type = V<>; };
	template <class... T> using multiple_t = typename Multiple<tuple, T...>::type;
	template <size_t N = 0, class T> void multiple_impl(T& t) const {
		if constexpr (N < tuple_size_v<T>) {
			auto& vec = get<N>(t);
			using V = typename remove_reference_t<decltype(vec)>::value_type;
			vec.push_back(read<V>());
			multiple_impl<N + 1>(t);
		}
	}

public:
	template <class... T> auto multiple(size_t h) const {
		multiple_t<T...> result;
		while (h--) multiple_impl(result);
		return result;
	}
} in;
#define inputs(T, ...) \
	T __VA_ARGS__;     \
	in(__VA_ARGS__)
#define ini(...) inputs(int, __VA_ARGS__)
#define inl(...) inputs(long long, __VA_ARGS__)
#define ins(...) inputs(string, __VA_ARGS__)
#line 7 "/home/yuruhiya/programming/library/template/Output.cpp"
#include <charconv>
#line 10 "/home/yuruhiya/programming/library/template/Output.cpp"
using namespace std;

struct BoolStr {
	const char *t, *f;
	BoolStr(const char* _t, const char* _f) : t(_t), f(_f) {}
} Yes("Yes", "No"), yes("yes", "no"), YES("YES", "NO"), Int("1", "0");
struct DivStr {
	const char *d, *l;
	DivStr(const char* _d, const char* _l) : d(_d), l(_l) {}
} spc(" ", "\n"), no_spc("", "\n"), end_line("\n", "\n"), comma(",", "\n"),
    no_endl(" ", "");
class Output {
	BoolStr B{Yes};
	DivStr D{spc};

public:
	void put(int v) const {
		char buf[12]{};
		if (auto [ptr, e] = to_chars(begin(buf), end(buf), v); e == errc{}) {
			fwrite(buf, sizeof(char), ptr - buf, stdout);
		} else {
			assert(false);
		}
	}
	void put(long long v) const {
		char buf[21]{};
		if (auto [ptr, e] = to_chars(begin(buf), end(buf), v); e == errc{}) {
			fwrite(buf, sizeof(char), ptr - buf, stdout);
		} else {
			assert(false);
		}
	}
	void put(bool v) const {
		put(v ? B.t : B.f);
	}
	void put(vector<bool>::reference v) const {
		put(v ? B.t : B.f);
	}
	void put(char v) const {
		putchar_unlocked(v);
	}
	void put(const char* v) const {
		fwrite_unlocked(v, 1, strlen(v), stdout);
	}
	void put(double v) const {
		printf("%.20f", v);
	}
	void put(long double v) const {
		printf("%.20Lf", v);
	}
	template <class T> void put(const T& v) const {
		cout << v;
	}
	template <class T, class U> void put(const pair<T, U>& v) const {
		put(v.first);
		put(D.d);
		put(v.second);
	}
	template <class InputIterater>
	void put_range(const InputIterater& begin, const InputIterater& end) const {
		for (InputIterater i = begin; i != end; ++i) {
			if (i != begin) put(D.d);
			put(*i);
		}
	}
	template <class T> void put(const vector<T>& v) const {
		put_range(v.begin(), v.end());
	}
	template <class T, size_t N> void put(const array<T, N>& v) const {
		put_range(v.begin(), v.end());
	}
	template <class T> void put(const vector<vector<T>>& v) const {
		for (size_t i = 0; i < v.size(); ++i) {
			if (i) put(D.l);
			put(v[i]);
		}
	}

	Output() = default;
	Output(const BoolStr& _boolstr, const DivStr& _divstr) : B(_boolstr), D(_divstr) {}
	Output& operator()() {
		put(D.l);
		return *this;
	}
	template <class H> Output& operator()(H&& h) {
		put(h);
		put(D.l);
		return *this;
	}
	template <class H, class... T> Output& operator()(H&& h, T&&... t) {
		put(h);
		put(D.d);
		return operator()(forward<T>(t)...);
	}
	template <class InputIterator>
	Output& range(const InputIterator& begin, const InputIterator& end) {
		put_range(begin, end);
		put(D.l);
		return *this;
	}
	template <class T> Output& range(const T& a) {
		range(a.begin(), a.end());
		return *this;
	}
	template <class... T> void exit(T&&... t) {
		operator()(forward<T>(t)...);
		std::exit(EXIT_SUCCESS);
	}
	Output& flush() {
		fflush_unlocked(stdout);
		return *this;
	}
	Output& set(const BoolStr& b) {
		B = b;
		return *this;
	}
	Output& set(const DivStr& d) {
		D = d;
		return *this;
	}
	Output& set(const char* t, const char* f) {
		B = BoolStr(t, f);
		return *this;
	}
} out;
#line 3 "/home/yuruhiya/programming/library/template/Step.cpp"
using namespace std;

template <class T> struct Step {
	using value_type = T;

	class iterator {
		value_type a, b, c;

	public:
		constexpr iterator() : a(value_type()), b(value_type()), c(value_type()) {}
		constexpr iterator(value_type _b, value_type _c, value_type _s)
		    : a(_b), b(_c), c(_s) {}
		constexpr iterator& operator++() {
			--b;
			a += c;
			return *this;
		}
		constexpr iterator operator++(int) {
			iterator tmp = *this;
			--b;
			a += c;
			return tmp;
		}
		constexpr const value_type& operator*() const {
			return a;
		}
		constexpr const value_type* operator->() const {
			return &a;
		}
		constexpr bool operator==(const iterator& i) const {
			return b == i.b;
		}
		constexpr bool operator!=(const iterator& i) const {
			return !(b == i.b);
		}
		constexpr value_type start() const {
			return a;
		}
		constexpr value_type size() const {
			return b;
		}
		constexpr value_type step() const {
			return c;
		}
	};
	constexpr Step(value_type b, value_type c, value_type s) : be(b, c, s) {}
	constexpr iterator begin() const {
		return be;
	}
	constexpr iterator end() const {
		return en;
	}
	constexpr value_type start() const {
		return be.start();
	}
	constexpr value_type size() const {
		return be.size();
	}
	constexpr value_type step() const {
		return be.step();
	}
	constexpr value_type sum() const {
		return start() * size() + step() * (size() * (size() - 1) / 2);
	}
	operator vector<value_type>() const {
		return to_a();
	}
	auto to_a() const {
		vector<value_type> result;
		result.reserve(size());
		for (auto i : *this) {
			result.push_back(i);
		}
		return result;
	}

private:
	iterator be, en;
};
template <class T> constexpr auto step(T a) {
	return Step<T>(0, a, 1);
}
template <class T> constexpr auto step(T a, T b) {
	return Step<T>(a, b - a, 1);
}
template <class T> constexpr auto step(T a, T b, T c) {
	return Step<T>(a, a < b ? (b - a - 1) / c + 1 : 0, c);
}
#line 8 "/home/yuruhiya/programming/library/template/Ruby.cpp"
using namespace std;

template <class F> struct Callable {
	F func;
	Callable(const F& f) : func(f) {}
};
template <class T, class F> auto operator|(const T& v, const Callable<F>& c) {
	return c.func(v);
}

struct Sort_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v), f);
			return v;
		});
	}
	template <class T> friend auto operator|(T v, [[maybe_unused]] const Sort_impl& c) {
		sort(begin(v), end(v));
		return v;
	}
} Sort;
struct SortBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v),
			     [&](const auto& i, const auto& j) { return f(i) < f(j); });
			return v;
		});
	}
} SortBy;
struct RSort_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(rbegin(v), rend(v), f);
			return v;
		});
	}
	template <class T> friend auto operator|(T v, [[maybe_unused]] const RSort_impl& c) {
		sort(rbegin(v), rend(v));
		return v;
	}
} RSort;
struct RSortBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			sort(begin(v), end(v),
			     [&](const auto& i, const auto& j) { return f(i) > f(j); });
			return v;
		});
	}
} RSortBy;
struct Reverse_impl {
	template <class T> friend auto operator|(T v, const Reverse_impl& c) {
		reverse(begin(v), end(v));
		return v;
	}
} Reverse;
struct Unique_impl {
	template <class T> friend auto operator|(T v, const Unique_impl& c) {
		v.erase(unique(begin(v), end(v), end(v)));
		return v;
	}
} Unique;
struct Uniq_impl {
	template <class T> friend auto operator|(T v, const Uniq_impl& c) {
		sort(begin(v), end(v));
		v.erase(unique(begin(v), end(v)), end(v));
		return v;
	}
} Uniq;
struct Rotate_impl {
	auto operator()(int&& left) {
		return Callable([&](auto v) {
			int s = static_cast<int>(size(v));
			assert(-s <= left && left <= s);
			if (0 <= left) {
				rotate(begin(v), begin(v) + left, end(v));
			} else {
				rotate(begin(v), end(v) + left, end(v));
			}
			return v;
		});
	}
} Rotate;
struct Max_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) { return *max_element(begin(v), end(v), f); });
	}
	template <class T> friend auto operator|(T v, const Max_impl& c) {
		return *max_element(begin(v), end(v));
	}
} Max;
struct Min_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) { return *min_element(begin(v), end(v), f); });
	}
	template <class T> friend auto operator|(T v, const Min_impl& c) {
		return *min_element(begin(v), end(v));
	}
} Min;
struct MaxPos_impl {
	template <class T> friend auto operator|(T v, const MaxPos_impl& c) {
		return max_element(begin(v), end(v)) - begin(v);
	}
} MaxPos;
struct MinPos_impl {
	template <class T> friend auto operator|(T v, const MinPos_impl& c) {
		return min_element(begin(v), end(v)) - begin(v);
	}
} MinPos;
struct MaxBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto max_it = begin(v);
			auto max_val = f(*max_it);
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); max_val < val) {
					max_it = it;
					max_val = val;
				}
			}
			return *max_it;
		});
	}
} MaxBy;
struct MinBy_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto min_it = begin(v);
			auto min_val = f(*min_it);
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); min_val > val) {
					min_it = it;
					min_val = val;
				}
			}
			return *min_it;
		});
	}
} MinBy;
struct MaxOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto max_val = f(*begin(v));
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); max_val < val) {
					max_val = val;
				}
			}
			return max_val;
		});
	}
} MaxOf;
struct MinOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			auto min_val = f(*begin(v));
			for (auto it = next(begin(v)); it != end(v); ++it) {
				if (auto val = f(*it); min_val > val) {
					min_val = val;
				}
			}
			return min_val;
		});
	}
} MinOf;
struct Count_impl {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) { return count(begin(v), end(v), val); });
	}
} Count;
struct CountIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) { return count_if(begin(v), end(v), f); });
	}
} CountIf;
struct Index_impl {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) -> optional<int> {
			auto result = find(begin(v), end(v), val);
			return result != end(v) ? optional(result - begin(v)) : nullopt;
		});
	}
} Index;
struct IndexIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) -> optional<int> {
			auto result = find_if(begin(v), end(v), f);
			return result != end(v) ? optional(result - begin(v)) : nullopt;
		});
	}
} IndexIf;
struct FindIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) -> optional<typename decltype(v)::value_type> {
			auto result = find_if(begin(v), end(v), f);
			return result != end(v) ? optional(*result) : nullopt;
		});
	}
} FindIf;
struct Sum_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			return accumulate(next(begin(v)), end(v), f(*begin(v)),
			                  [&](const auto& a, const auto& b) { return a + f(b); });
		});
	}
	template <class T> friend auto operator|(T v, const Sum_impl& c) {
		return accumulate(begin(v), end(v), typename T::value_type{});
	}
} Sum;
struct Includes {
	template <class V> auto operator()(const V& val) {
		return Callable([&](auto v) { return find(begin(v), end(v), val) != end(v); });
	}
} Includes;
struct IncludesIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) { return find_if(begin(v), end(v), f) != end(v); });
	}
} IncludesIf;
struct RemoveIf_impl {
	template <class F> auto operator()(const F& f) {
		return Callable([&](auto v) {
			v.erase(remove_if(begin(v), end(v), f), end(v));
			return v;
		});
	}
} RemoveIf;
struct Each_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				f(i);
			}
		});
	}
} Each;
struct Select_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			using value_type = typename decltype(v)::value_type;
			vector<value_type> result;
			for (const auto& i : v) {
				if (f(i)) result.push_back(i);
			}
			return result;
		});
	}
} Select;
struct Map_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			using result_type = invoke_result_t<F, typename decltype(v)::value_type>;
			vector<result_type> result;
			result.reserve(size(v));
			for (const auto& i : v) {
				result.push_back(f(i));
			}
			return result;
		});
	}
} Map;
struct Indexed_impl {
	template <class T> friend auto operator|(const T& v, Indexed_impl& c) {
		using value_type = typename T::value_type;
		vector<pair<value_type, int>> result;
		result.reserve(size(v));
		int index = 0;
		for (const auto& i : v) {
			result.emplace_back(i, index++);
		}
		return result;
	}
} Indexed;
struct AllOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (!f(i)) return false;
			}
			return true;
		});
	}
} AllOf;
struct AnyOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (f(i)) return true;
			}
			return false;
		});
	}
} AnyOf;
struct NoneOf_impl {
	template <class F> auto operator()(F&& f) {
		return Callable([&](auto v) {
			for (const auto& i : v) {
				if (f(i)) return false;
			}
			return true;
		});
	}
} NoneOf;

struct Tally_impl {
	template <class F> auto operator()(size_t max_val) {
		return Callable([&](auto v) {
			vector<size_t> result(max_val);
			for (const auto& i : v) {
				result[static_cast<size_t>(i)]++;
			}
			return result;
		});
	}
	template <class T, class value_type = typename T::value_type>
	friend auto operator|(const T& v, Tally_impl& c) {
		map<value_type, size_t> result;
		for (const auto& i : v) {
			result[i]++;
		}
		return result;
	}
} Tally;

template <class T> auto operator*(const vector<T>& a, size_t n) {
	T result;
	for (size_t i = 0; i < n; ++i) {
		result.insert(result.end(), a.begin(), a.end());
	}
	return result;
}
auto operator*(string a, size_t n) {
	string result;
	for (size_t i = 0; i < n; ++i) {
		result += a;
	}
	return result;
}
template <class T, class U> auto& operator<<(vector<T>& a, const U& b) {
	a.insert(a.end(), all(b));
	return a;
}
template <class T> auto& operator<<(string& a, const T& b) {
	a.insert(a.end(), all(b));
	return a;
}
template <class T, class U> auto operator+(vector<T> a, const U& b) {
	a << b;
	return a;
}
template <class T> auto operator+(string a, const T& b) {
	a << b;
	return a;
}
#line 6 "/home/yuruhiya/programming/library/template/functions.cpp"
using namespace std;

template <class T> int sz(const T& v) {
	return v.size();
}
template <class T, class U> int lower_index(const T& a, const U& v) {
	return lower_bound(all(a), v) - a.begin();
}
template <class T, class U> int upper_index(const T& a, const U& v) {
	return upper_bound(all(a), v) - a.begin();
}
template <class T> auto Slice(const T& v, size_t i, size_t len) {
	return i < v.size() ? T(v.begin() + i, v.begin() + min(i + len, v.size())) : T();
}
template <class T> T div_ceil(T n, T m) {
	return (n + m - 1) / m;
}
template <class T> T div_ceil2(T n, T m) {
	return div_ceil(n, m) * m;
}
template <class T> T triangle(T n) {
	return (n & 1) ? (n + 1) / 2 * n : n / 2 * (n + 1);
}
template <class T> T nC2(T n) {
	return (n & 1) ? (n - 1) / 2 * n : n / 2 * (n - 1);
}
template <class T> T middle(const T& l, const T& r) {
	return l + (r - l) / 2;
}
template <class T> bool chmax(T& a, const T& b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}
template <class T> bool chmin(T& a, const T& b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T> bool in_range(const T& v, const T& min, const T& max) {
	return min <= v && v < max;
}
template <class T> bool in_square(T n) {
	T s = sqrt(n);
	return s * s == n || (s + 1) * (s + 1) == n;
}
template <class T = long long> T BIT(int b) {
	return T(1) << b;
}
template <class T, class U = typename T::value_type> U Gcdv(const T& v) {
	return accumulate(next(v.begin()), v.end(), U(*v.begin()), gcd<U, U>);
}
template <class T, class U = typename T::value_type> U Lcmv(const T& v) {
	return accumulate(next(v.begin()), v.end(), U(*v.begin()), lcm<U, U>);
}
template <class T, class U> T Pow(T a, U n) {
	T result = 1;
	while (n > 0) {
		if (n & 1) {
			result *= a;
			n--;
		} else {
			a *= a;
			n >>= 1;
		}
	}
	return result;
}
template <class T, class U> T Powmod(T a, U n, T mod) {
	T result = 1;
	while (n > 0) {
		if (n & 1) {
			result = result * a % mod;
			n--;
		} else {
			a = a * a % mod;
			n >>= 1;
		}
	}
	return result;
}
namespace internal {
	template <class T, size_t N> auto make_vector(vector<int>& sizes, const T& init) {
		if constexpr (N == 1) {
			return vector(sizes[0], init);
		} else {
			int size = sizes[N - 1];
			sizes.pop_back();
			return vector(size, make_vector<T, N - 1>(sizes, init));
		}
	}
}  // namespace internal
template <class T, size_t N>
auto make_vector(const int (&sizes)[N], const T& init = T()) {
	vector s(rbegin(sizes), rend(sizes));
	return internal::make_vector<T, N>(s, init);
}
#line 9 "/home/yuruhiya/programming/library/template/template.cpp"
#if __has_include(<library/dump.hpp>)
#include <library/dump.hpp>
#define LOCAL
#else
#define dump(...) ((void)0)
#endif

template <class T> constexpr T oj_local(const T& oj, const T& local) {
#ifndef LOCAL
	return oj;
#else
	return local;
#endif
}
#line 2 "a.cpp"

int solve(int limit, int n, int m, int x) {
	auto [s_name, s_weight, s_value] = in.multiple<string, int, int>(n);
	auto [name, weight, value] = in.multiple<string, int, int>(m);

	auto dp = make_vector<int>({m + 1, limit + 1}, -1);
	rep(i, limit + 1) dp[0][i] = 0;
	rep(i, m) {
		auto dp2 = dp;
		rep(j, m + 1) rep(k, limit) {
			if (j < m && k + weight[i] <= limit && dp[j][k] != -1) {
				chmax(dp2[j + 1][k + weight[i]], dp[j][k] + value[i]);
			}
			chmax(dp2[j][k + 1], dp2[j][k]);
		}
		dp = dp2;
	}

	int ans = 0;
	auto update = [&](int val, int wei) {
		FOR(i, x, m + 1) {
			if (limit - wei >= 0) {
				chmax(ans, dp[i][limit - wei] + val);
			}
		}
	};
	rep(i, n) {
		update(s_value[i], s_weight[i]);
	}
	rep(i, n) FOR(j, i + 1, n) {
		update(s_value[i] + s_value[j], s_weight[i] + s_weight[j]);
	}
	return ans;
}

int main() {
	while (true) {
		ini(limit, n, m, x);
		if (n == 0) break;
		out(solve(limit, n, m, x));
	}
}
accuracy: 1
time_ms: 40
memory_kb: 3644
final_rank: 12

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;}

struct artist{
    int cost;
    int val;

    void READ(){
        char name[33];
        scanf(" %s %d %d", name, &cost, &val);
    }
};

const int M = 111;
const int L = 1001;
const int INF = 10101010;

int dp[M][M][L];
int mx[L];

int main(){
    int lim,n,m,x;
    while(scanf(" %d %d %d %d", &lim, &n, &m, &x),lim){
        vector<artist> a(n),b(m);
        rep(i,n) a[i].READ();
        rep(i,m) b[i].READ();

        rep(i,M)rep(j,M)rep(k,L) dp[i][j][k] = -INF;
        dp[0][0][0] = 0;
        rep(i,m)rep(j,i+1)rep(k,L)if(dp[i][j][k]>=0){
            dp[i+1][j][k] = max(dp[i+1][j][k], dp[i][j][k]);

            int nk = k+b[i].cost;
            if(nk<L) dp[i+1][j+1][nk] = max(dp[i+1][j+1][nk], dp[i][j][k]+b[i].val);
        }

        rep(i,L) mx[i] = -INF;
        for(int i=x; i<=m; ++i)rep(j,L) mx[j] = max(mx[j], dp[m][i][j]);
        rep(i,L-1) mx[i+1] = max(mx[i+1],mx[i]);

        int ans = -INF;
        rep(i,n){
            int rem = lim-a[i].cost;
            if(rem<0) continue;
            ans = max(ans, a[i].val+mx[rem]);

            rep(j,n)if(i!=j){
                int rr = rem-a[j].cost;
                if(rr<0) continue;
                ans = max(ans, a[i].val+a[j].val+mx[rr]);
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 51352
final_rank: 19

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<n;i++)
using namespace std;

int limit,n,m,x;

int a[111],b[111],c[111],d[111];
string damy;
int dp[1111][111];
bool used[1111][111];
int MAX[1111];

void Input(){
  rep(i,m){
    cin>>damy>>c[i]>>d[i];
  }
  rep(i,n){
    cin>>damy>>a[i]>>b[i];
  }
}

void init(){
  memset(MAX,0,sizeof(MAX));
  memset(dp,0,sizeof(dp));
  memset(used,0,sizeof(used));
}

void DP(){
  used[0][0]=1;
  for(int k=0;k<n;k++){
    for(int i=limit;i>=0;i--){
      for(int j=n;j>=0;j--){
	if(used[i][j]){
	  if(i+a[k]<=limit){
	    used[i+a[k]][j+1]=1;
	    dp[i+a[k]][j+1]=max(dp[i+a[k]][j+1],dp[i][j]+b[k]);
	  }
	}
      }
    }
  }

  for(int i=0;i<=limit;i++){
    for(int j=x;j<=n;j++){
      MAX[i]=max(MAX[i],dp[i][j]);
    }
  }

  int ans=0;

  for(int i=0;i<m;i++){
    for(int j=i+1;j<m;j++){
      for(int k=0;k<limit;k++){
	if(k+c[i]+c[j]>limit)break;
	ans=max(ans,MAX[k]+d[i]+d[j]);
      }
    }
  }

  for(int i=0;i<m;i++){
    for(int k=0;k<limit;k++){
      if(k+c[i]>limit)break;
      ans=max(ans,MAX[k]+d[i]);
    }
  }

  cout << ans << endl;
  
}


int main(){
  while( cin>>limit>>m>>n>>x,limit){
    Input();
    init();
    DP();
  }
}
accuracy: 1
time_ms: 20
memory_kb: 3612
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
Int dp[111][1111];

template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
signed main(){  
  cin.tie(0);
  ios::sync_with_stdio(0);
  Int l,n,m,x;
  while(cin>>l>>n>>m>>x,l){
    string st;
    vector<Int> se(n),ss(n);
    vector<Int> e(m),s(m);
    for(Int i=0;i<n;i++) cin>>st>>se[i]>>ss[i];
    for(Int i=0;i<m;i++) cin>>st>>e[i]>>s[i];
    
    const Int INF = 1e9;
    for(Int i=0;i<111;i++)
      for(Int j=0;j<1111;j++)
	dp[i][j]=-INF;

    dp[0][0]=0;
    for(Int k=0;k<m;k++)
      for(Int i=m;i>=0;i--)
	for(Int j=l;j>=0;j--)
	  chmax(dp[i+1][j+e[k]],dp[i][j]+s[k]);
    
    vector<Int> dp2(l+1,-INF);
    for(Int i=x;i<=m;i++)
      for(Int j=0;j<=l;j++)
	chmax(dp2[j],dp[i][j]);

    for(Int j=1;j<=l;j++) chmax(dp2[j],dp2[j-1]);

    Int ans=-INF;
    for(Int i=0;i<n;i++){
      if(se[i]>l) continue;
      chmax(ans,dp2[l-se[i]]+ss[i]);
      for(Int j=0;j<i;j++){
	if(se[i]+se[j]>l) continue;
	chmax(ans,dp2[l-(se[i]+se[j])]+ss[i]+ss[j]);
      }
    }
    cout<<ans<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4156
final_rank: 6

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<n;i++)
using namespace std;

int limit,n,m,x;

int a[111],b[111],c[111],d[111];
string damy;
int dp[1111][111];
bool used[1111][111];
int MAX[1111];

void Input(){
  rep(i,m){
    cin>>damy>>c[i]>>d[i];
  }
  rep(i,n){
    cin>>damy>>a[i]>>b[i];
  }
}

void init(){
  memset(MAX,0,sizeof(MAX));
  memset(dp,0,sizeof(dp));
  memset(used,0,sizeof(used));
}

void DP(){
  used[0][0]=1;
  for(int k=0;k<n;k++){
    for(int i=limit;i>=0;i--){
      for(int j=n;j>=0;j--){
	if(used[i][j]){
	  if(i+a[k]<=limit){
	    used[i+a[k]][j+1]=1;
	    dp[i+a[k]][j+1]=max(dp[i+a[k]][j+1],dp[i][j]+b[k]);
	  }
	}
      }
    }
  }

  for(int i=0;i<=limit;i++){
    for(int j=x;j<=n;j++){
      MAX[i]=max(MAX[i],dp[i][j]);
    }
  }

  int ans=0;

  for(int i=0;i<m;i++){
    for(int j=i+1;j<m;j++){
      for(int k=0;k<limit;k++){
	if(k+c[i]+c[j]>limit)break;
	ans=max(ans,MAX[k]+d[i]+d[j]);
      }
    }
  }

  for(int i=0;i<m;i++){
    for(int k=0;k<limit;k++){
      if(k+c[i]>limit)break;
      ans=max(ans,MAX[k]+d[i]);
    }
  }

  cout << ans << endl;
  
}


int main(){
  while( cin>>limit>>m>>n>>x,limit){
    Input();
    init();
    DP();
  }
}
accuracy: 1
time_ms: 20
memory_kb: 3756
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
Int dp[111][1111];

template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
signed main(){  
  cin.tie(0);
  ios::sync_with_stdio(0);
  Int l,n,m,x;
  while(cin>>l>>n>>m>>x,l){
    string st;
    vector<Int> se(n),ss(n);
    vector<Int> e(m),s(m);
    for(Int i=0;i<n;i++) cin>>st>>se[i]>>ss[i];
    for(Int i=0;i<m;i++) cin>>st>>e[i]>>s[i];
    
    const Int INF = 1e9;
    for(Int i=0;i<111;i++)
      for(Int j=0;j<1111;j++)
	dp[i][j]=-INF;

    dp[0][0]=0;
    for(Int k=0;k<m;k++)
      for(Int i=m;i>=0;i--)
	for(Int j=l;j>=0;j--)
	  chmax(dp[i+1][j+e[k]],dp[i][j]+s[k]);
    
    vector<Int> dp2(l+1,-INF);
    for(Int i=x;i<=m;i++)
      for(Int j=0;j<=l;j++)
	chmax(dp2[j],dp[i][j]);

    for(Int j=1;j<=l;j++) chmax(dp2[j],dp2[j-1]);

    Int ans=-INF;
    for(Int i=0;i<n;i++){
      if(se[i]>l) continue;
      chmax(ans,dp2[l-se[i]]+ss[i]);
      for(Int j=0;j<i;j++){
	if(se[i]+se[j]>l) continue;
	chmax(ans,dp2[l-(se[i]+se[j])]+ss[i]+ss[j]);
      }
    }
    cout<<ans<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4036
final_rank: 4

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

int LIMIT,N,M,X;

struct Info{
	int cost,value;
};

struct Data{
	Data(int arg_num,int arg_cost){
		num = arg_num;
		cost = arg_cost;
	}
	int num,cost;
};

void func(){

	Info sec[N];

	char buf[31];

	for(int i = 0; i < N; i++){
		scanf("%s %d %d",buf,&sec[i].cost,&sec[i].value);
	}

	int dp_sec[3][21],next_sec[3][21];

	for(int num = 0; num <= 2; num++){
		for(int total_cost = 0; total_cost <= 20; total_cost++){
			dp_sec[num][total_cost] = -1;
			next_sec[num][total_cost] = -1;
		}
	}

	dp_sec[0][0] = 0;
	next_sec[0][0] = 0;

	vector<Data> Updated;

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

		for(int num = 0; num <= 1; num++){
			for(int total_cost = 0; total_cost+sec[i].cost <= 20; total_cost++){
				if(dp_sec[num][total_cost] == -1)continue;

				if(next_sec[num+1][total_cost+sec[i].cost] < dp_sec[num][total_cost]+sec[i].value){
					next_sec[num+1][total_cost+sec[i].cost] = dp_sec[num][total_cost]+sec[i].value;
					Updated.push_back(Data(num+1,total_cost+sec[i].cost));
				}
			}
		}

		for(int k = 0; k < Updated.size(); k++){
			dp_sec[Updated[k].num][Updated[k].cost] = next_sec[Updated[k].num][Updated[k].cost];
		}
		Updated.clear();
	}

	Info stan[M];
	int cost_sum = 0;

	for(int i = 0; i < M; i++){
		scanf("%s %d %d",buf,&stan[i].cost,&stan[i].value);
		cost_sum += stan[i].cost;
	}

	int dp_stan[M+1][cost_sum+1],next_stan[M+1][cost_sum+1];

	for(int num = 0; num <= M; num++){
		for(int total_cost = 0; total_cost <= cost_sum; total_cost++){
			dp_stan[num][total_cost] = -1;
			next_stan[num][total_cost] = -1;
		}
	}

	dp_stan[0][0] = 0;
	next_stan[0][0] = 0;
	Updated.clear();

	for(int i = 0; i < M; i++){ //100

		for(int num = 0; num <= M-1; num++){ //100
			for(int total_cost = 0; total_cost+stan[i].cost <= cost_sum; total_cost++){ //1000
				if(dp_stan[num][total_cost] == -1)continue;

				if(next_stan[num+1][total_cost+stan[i].cost] < dp_stan[num][total_cost]+stan[i].value){
					next_stan[num+1][total_cost+stan[i].cost] = dp_stan[num][total_cost]+stan[i].value;
					Updated.push_back(Data(num+1,total_cost+stan[i].cost));
				}
			}
		}

		for(int k = 0; k < Updated.size(); k++){
			dp_stan[Updated[k].num][Updated[k].cost] = next_stan[Updated[k].num][Updated[k].cost];
		}
		Updated.clear();
	}

	int ans = 0;

	for(int sec_num = 1; sec_num <= 2; sec_num++){
		for(int sec_cost = 0; sec_cost <= 20; sec_cost++){
			if(dp_sec[sec_num][sec_cost] == -1)continue;
			for(int stan_num = X; stan_num <= M; stan_num++){
				for(int stan_cost = 0; stan_cost <= min(LIMIT,cost_sum); stan_cost++){
					if(dp_stan[stan_num][stan_cost] == -1)continue;
					if(sec_cost+stan_cost > LIMIT)continue;

					ans = max(ans,dp_sec[sec_num][sec_cost]+dp_stan[stan_num][stan_cost]);
				}
			}
		}
	}

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

int main(){

	while(true){
		scanf("%d %d %d %d",&LIMIT,&N,&M,&X);
		if(LIMIT == 0 && N == 0 && M == 0 && X == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3748
final_rank: 3

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

int LIMIT,N,M,X;
int dp_sec[3][21],next_sec[3][21];
int dp_stan[101][1001],next_stan[101][1001];

struct Info{
	int cost,value;
};

struct Data{
	Data(int arg_num,int arg_cost){
		num = arg_num;
		cost = arg_cost;
	}
	int num,cost;
};

void func(){

	Info sec[N];

	char buf[31];

	for(int i = 0; i < N; i++){
		scanf("%s %d %d",buf,&sec[i].cost,&sec[i].value);
	}

	for(int num = 0; num <= 2; num++){
		for(int total_cost = 0; total_cost <= 20; total_cost++){
			dp_sec[num][total_cost] = -1;
			next_sec[num][total_cost] = -1;
		}
	}

	dp_sec[0][0] = 0;
	next_sec[0][0] = 0;

	vector<Data> Updated;

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

		for(int num = 0; num <= 1; num++){
			for(int total_cost = 0; total_cost+sec[i].cost <= 20; total_cost++){
				if(dp_sec[num][total_cost] == -1)continue;

				if(next_sec[num+1][total_cost+sec[i].cost] < dp_sec[num][total_cost]+sec[i].value){
					next_sec[num+1][total_cost+sec[i].cost] = dp_sec[num][total_cost]+sec[i].value;
					Updated.push_back(Data(num+1,total_cost+sec[i].cost));
				}
			}
		}

		for(int k = 0; k < Updated.size(); k++){
			dp_sec[Updated[k].num][Updated[k].cost] = next_sec[Updated[k].num][Updated[k].cost];
		}
		Updated.clear();
	}

	Info stan[M];
	int cost_sum = 0;

	for(int i = 0; i < M; i++){
		scanf("%s %d %d",buf,&stan[i].cost,&stan[i].value);
		cost_sum += stan[i].cost;
	}

	for(int num = 0; num <= M; num++){
		for(int total_cost = 0; total_cost <= 1000; total_cost++){
			dp_stan[num][total_cost] = -1;
			next_stan[num][total_cost] = -1;
		}
	}

	dp_stan[0][0] = 0;
	next_stan[0][0] = 0;
	Updated.clear();

	for(int i = 0; i < M; i++){ //100

		for(int num = 0; num <= M-1; num++){ //100
			for(int total_cost = 0; total_cost+stan[i].cost <= cost_sum; total_cost++){ //1000
				if(dp_stan[num][total_cost] == -1)continue;

				if(next_stan[num+1][total_cost+stan[i].cost] < dp_stan[num][total_cost]+stan[i].value){
					next_stan[num+1][total_cost+stan[i].cost] = dp_stan[num][total_cost]+stan[i].value;
					Updated.push_back(Data(num+1,total_cost+stan[i].cost));
				}
			}
		}

		for(int k = 0; k < Updated.size(); k++){
			dp_stan[Updated[k].num][Updated[k].cost] = next_stan[Updated[k].num][Updated[k].cost];
		}
		Updated.clear();
	}

	int ans = 0;

	for(int sec_num = 1; sec_num <= 2; sec_num++){
		for(int sec_cost = 0; sec_cost <= 20; sec_cost++){
			if(dp_sec[sec_num][sec_cost] == -1)continue;
			for(int stan_num = X; stan_num <= M; stan_num++){
				for(int stan_cost = 0; stan_cost <= LIMIT; stan_cost++){
					if(dp_stan[stan_num][stan_cost] == -1)continue;
					if(sec_cost+stan_cost > LIMIT)continue;

					ans = max(ans,dp_sec[sec_num][sec_cost]+dp_stan[stan_num][stan_cost]);
				}
			}
		}
	}

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

int main(){

	while(true){
		scanf("%d %d %d %d",&LIMIT,&N,&M,&X);
		if(LIMIT == 0 && N == 0 && M == 0 && X == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4084
final_rank: 5

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

using namespace std;

#define MAX 1010
#define MAX_M 101

int dp[MAX_M][MAX];

int main()
{
    int LIMIT, N, M, X;
    string name;
    while (cin >> LIMIT >> N >> M >> X, LIMIT) {
        vector<int> c(N), s(N);
        for (int i = 0; i < N; i++) {
            cin >> name >> c[i] >> s[i];
        }
        int max_s[MAX];
        fill(max_s, max_s + MAX, -1);
        for (int i = 0; i < N; i++) {
            max_s[c[i]] = max(max_s[c[i]], s[i]);
            for (int j = i + 1; j < N; j++) {
                max_s[c[i] + c[j]] = max(max_s[c[i] + c[j]], s[i] + s[j]);
            }
        }
        for (int i = 0; i < LIMIT; i++) {
            max_s[i+1] = max(max_s[i+1], max_s[i]);
        }
        vector<int> sc(M), ss(M);
        for (int i = 0; i < M; i++) {
            cin >> name >> sc[i] >> ss[i];
        }
        for (int i = 0; i <= M; i++) {
            for (int j = 0; j <= LIMIT; j++) {
                dp[i][j] = -1;
            }
        }
        dp[0][0] = 0;
        for (int i = 0; i < M; i++) {
            for (int j = M-1; j >= 0; j--) {
                for (int k = LIMIT-sc[i]; k >= 0; k--) {
                    if (dp[j][k] == -1) continue;
                    int nk = k + sc[i];
                    if (nk <= LIMIT) {
                        dp[j+1][nk] = max(dp[j+1][nk], dp[j][k] + ss[i]);
                    }
                }
            }
        }
        
        int res = 0;
        for (int i = 0; i <= LIMIT; i++) {
            if (max_s[i] == -1) continue;
            for (int j = X; j <= M; j++) {
                if (dp[j][LIMIT-i] == -1) continue;
                res = max(res, max_s[i] + dp[j][LIMIT-i]);                   
            }
        }
        cout << res << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3540
final_rank: 1

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

using namespace std;

#define MAX 1010
#define MAX_M 101

int dp[MAX_M][MAX_M][MAX];

int main()
{
    int LIMIT, N, M, X;
    string name;
    while (cin >> LIMIT >> N >> M >> X, LIMIT) {
        vector<int> c(N), s(N);
        for (int i = 0; i < N; i++) {
            cin >> name >> c[i] >> s[i];
        }
        int max_s[MAX];
        fill(max_s, max_s + MAX, -1);
        for (int i = 0; i < N; i++) {
            max_s[c[i]] = max(max_s[c[i]], s[i]);
            for (int j = i + 1; j < N; j++) {
                max_s[c[i] + c[j]] = max(max_s[c[i] + c[j]], s[i] + s[j]);
            }
        }
        for (int i = 0; i < LIMIT; i++) {
            max_s[i+1] = max(max_s[i+1], max_s[i]);
        }
        vector<int> sc(M), ss(M);
        for (int i = 0; i < M; i++) {
            cin >> name >> sc[i] >> ss[i];
        }
        for (int i = 0; i <= M; i++) {
            for (int j = 0; j <= M; j++) {
                for (int k = 0; k <= LIMIT; k++) {
                    dp[i][j][k] = -1;
                }
            }
            dp[i][0][0] = 0;
        }
        
        for (int i = 0; i < M; i++) {
            for (int j = 0; j <= M; j++) {
                for (int k = LIMIT; k >= 0; k--) {
                    if (dp[i][j][k] == -1) continue;
                    int nk = k + sc[i];
                    dp[i+1][j][k] = max(dp[i+1][j][k], dp[i][j][k]);
                    if (nk <= LIMIT) {
                        dp[i+1][j+1][nk] = max(dp[i+1][j+1][nk], dp[i][j][k] + ss[i]);
                    }
                }
            }
        }  
        
        int res = 0;
        for (int i = 0; i <= LIMIT; i++) {
            if (max_s[i] == -1) continue;
            for (int j = 0; j <= M; j++) {
                for (int k = X; k <= M; k++) {
                    if (dp[j][k][LIMIT-i] == -1) continue;
                    res = max(res, max_s[i] + dp[j][k][LIMIT-i]);                   
                }
            }
        }
        cout << res << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 41452
final_rank: 15

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

using namespace std;

#define MAX 1010
#define MAX_M 101

int dp[MAX_M][MAX_M][MAX];

int main()
{
    int LIMIT, N, M, X;
    string name;
    while (cin >> LIMIT >> N >> M >> X, LIMIT) {
        vector<int> c(N), s(N);
        for (int i = 0; i < N; i++) {
            cin >> name >> c[i] >> s[i];
        }
        int max_s[MAX];
        fill(max_s, max_s + MAX, -1);
        for (int i = 0; i < N; i++) {
            max_s[c[i]] = max(max_s[c[i]], s[i]);
            for (int j = i + 1; j < N; j++) {
                max_s[c[i] + c[j]] = max(max_s[c[i] + c[j]], s[i] + s[j]);
            }
        }
        for (int i = 0; i < LIMIT; i++) {
            max_s[i+1] = max(max_s[i+1], max_s[i]);
        }
        vector<int> sc(M), ss(M);
        for (int i = 0; i < M; i++) {
            cin >> name >> sc[i] >> ss[i];
        }
        for (int i = 0; i <= M; i++) {
            for (int j = 0; j <= M; j++) {
                for (int k = 0; k <= LIMIT; k++) {
                    dp[i][j][k] = -1;
                }
            }
            dp[i][0][0] = 0;
        }
        
        for (int i = 0; i < M; i++) {
            for (int j = 0; j <= M; j++) {
                for (int k = LIMIT; k >= 0; k--) {
                    if (dp[i][j][k] == -1) continue;
                    int nk = k + sc[i];
                    dp[i+1][j][k] = max(dp[i+1][j][k], dp[i][j][k]);
                    dp[i+1][j+1][nk] = max(dp[i+1][j+1][nk], dp[i][j][k] + ss[i]);
                }
            }
        }  
        
        int res = 0;
        for (int i = 0; i <= LIMIT; i++) {
            if (max_s[i] == -1) continue;
            for (int j = 0; j <= M; j++) {
                for (int k = X; k <= M; k++) {
                    if (dp[j][k][LIMIT-i] == -1) continue;
                    res = max(res, max_s[i] + dp[j][k][LIMIT-i]);                   
                }
            }
        }
        cout << res << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 41456
final_rank: 16

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

/* constant */

const int MAX_L = 1000;
const int MAX_N = 100;
const int MAX_M = 100;

/* typedef */

typedef pair<int,int> pii;

/* global variables */

int lim, n, m, x;
pii secs[MAX_N], stds[MAX_M];
int dp0[3][MAX_L + 1], dp1[MAX_M + 1][MAX_L + 1];

/* subroutines */

/* main */

int main() {
  for (;;) {
    cin >> lim >> n >> m >> x;
    if (lim == 0) break;

    string name;
    for (int i = 0; i < n; i++)
      cin >> name >> secs[i].first >> secs[i].second;
    for (int i = 0; i < m; i++)
      cin >> name >> stds[i].first >> stds[i].second;

    memset(dp0, -1, sizeof(dp0));
    dp0[0][0] = 0;

    for (int i = 0; i < n; i++) {
      int &ei = secs[i].first, &si = secs[i].second;
      int maxl = lim - ei;
      for (int j = 1; j >= 0; j--)
	for (int l = 0; l <= maxl; l++)
	  if (dp0[j][l] >= 0 && dp0[j + 1][l + ei] < dp0[j][l] + si)
	    dp0[j + 1][l + ei] = dp0[j][l] + si;
    }

    for (int i = 1; i <= 2; i++)
      for (int l = 1; l <= lim; l++)
	if (dp0[i][l] < dp0[i][l - 1]) dp0[i][l] = dp0[i][l - 1];
    
    memset(dp1, -1, sizeof(dp1));
    dp1[0][0] = 0;

    for (int i = 0; i < m; i++) {
      int &ei = stds[i].first, &si = stds[i].second;
      int maxl = lim - ei;
      for (int j = m - 1; j >= 0; j--)
	for (int l = 0; l <= maxl; l++)
	  if (dp1[j][l] >= 0 && dp1[j + 1][l + ei] < dp1[j][l] + si)
	    dp1[j + 1][l + ei] = dp1[j][l] + si;
    }
    
    for (int i = 1; i <= m; i++)
      for (int l = 1; l <= lim; l++)
	if (dp1[i][l] < dp1[i][l - 1]) dp1[i][l] = dp1[i][l - 1];

    int maxsum = 0;

    for (int i = 1; i <= 2; i++)
      for (int j = x; j <= m; j++)
	for (int l = 0; l <= lim; l++)
	  if (dp0[i][l] >= 0 && dp1[j][lim - l] >= 0) {
	    int sum = dp0[i][l] + dp1[j][lim - l];
	    if (maxsum < sum) maxsum = sum;
	  }

    cout << maxsum << endl;
  }

  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 1620
final_rank: 2

code_snippet: #include <algorithm>
#include <functional>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <vector>
#include <list>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <bitset>
#include <climits>

#define all(c) (c).begin(), (c).end()
#define rep(i,n) for(int i=0;i<(n);i++)
#define pb(e) push_back(e)
#define mp(a, b) make_pair(a, b)
#define fr first
#define sc second

const int INF=100000000;
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
using namespace std;
typedef pair<int ,int > P;
typedef long long ll;
template<class T>
bool chmax(T &a, const T &b) {
    if(a<b) {
        a=b;
        return true;
    }

    return false;
}
struct Artist {
    int e,s;
    Artist(int e=0,int s=0) :
        e(e),s(s) {}
};
void input(int len, Artist *a) {
    rep(i,len) {
        string ss;
        int e,s;
        cin>>ss>>e>>s;
        a[i]=Artist(e,s);
    }
}
Artist artist1[102], artist2[102];
// ??????????????????????????°?????????
int dp1[102][5][1003];
int dp2[102][102][1003];

int lim,n,m,x;

void solve() {
    rep(i,102) rep(j,5) rep(k,1003) dp1[i][j][k]=-1;
    rep(i,102) rep(j,102) rep(k,1003) dp2[i][j][k]=-1;

    input(n,artist1);
    input(m,artist2);
    dp1[0][0][0]=dp2[0][0][0]=0;

    rep(k,lim) rep(i,n) rep(j,3) {
        Artist a=artist1[i];
        int lim_n = k+a.e;
        if(lim_n <= lim&&dp1[i][j][k]!=-1) 
            chmax(dp1[i+1][j+1][lim_n],dp1[i][j][k]+a.s);
        chmax(dp1[i+1][j][k],dp1[i][j][k]);
    }
    rep(k,lim) rep(i,m) rep(j,m) {
        Artist a=artist2[i];
        int lim_n = k+a.e;
        if(lim_n <= lim&&dp2[i][j][k]!=-1) 
            chmax(dp2[i+1][j+1][lim_n],dp2[i][j][k]+a.s);
        chmax(dp2[i+1][j][k],dp2[i][j][k]);
    }

    //rep(i,20) printf("%d %d\n",i,dp1[n][2][i]);
    //rep(i,20) printf("%d %d\n",i,dp2[m][2][i]);

    int ans=0;
    rep(i,lim) {
        int max1=max(dp1[n][1][i],dp1[n][2][i]);
        int max2=0;
        for(int j=x;j<=m;j++) for(int k=0;k<=lim-i;k++) chmax(max2,dp2[m][j][k]);

        chmax(ans,max1+max2);
        // printf("%d %d : %d\n",i,lim-i,max1+max2);
    }

    cout<<ans<<endl;
}

int main() {
    while(cin>>lim>>n>>m>>x) {
        if(lim+n+m+x==0) break;
        solve();
    }
    return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 43968
final_rank: 20

code_snippet: #include <algorithm>
#include <functional>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <vector>
#include <list>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <bitset>
#include <climits>

#define all(c) (c).begin(), (c).end()
#define rep(i,n) for(int i=0;i<(n);i++)
#define pb(e) push_back(e)
#define mp(a, b) make_pair(a, b)
#define fr first
#define sc second

const int INF=100000000;
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
using namespace std;
typedef pair<int ,int > P;
typedef long long ll;
template<class T>
bool chmax(T &a, const T &b) {
    if(a<b) {
        a=b;
        return true;
    }

    return false;
}
struct Artist {
    int e,s;
    Artist(int e=0,int s=0) :
        e(e),s(s) {}
};
void input(int len, Artist *a) {
    rep(i,len) {
        string ss;
        int e,s;
        cin>>ss>>e>>s;
        a[i]=Artist(e,s);
    }
}
Artist artist1[102], artist2[102];
// ??????????????????????????°?????????
int dp1[102][5][1003];
int dp2[102][102][1003];

int lim,n,m,x;

void solve() {
    rep(i,102) rep(j,5) rep(k,1003) dp1[i][j][k]=-1;
    rep(i,102) rep(j,102) rep(k,1003) dp2[i][j][k]=-1;

    input(n,artist1);
    input(m,artist2);
    dp1[0][0][0]=dp2[0][0][0]=0;

    rep(i,n) rep(j,3) rep(k,lim) {
        Artist a=artist1[i];
        int lim_n = k+a.e;
        if(lim_n <= lim&&dp1[i][j][k]!=-1) 
            chmax(dp1[i+1][j+1][lim_n],dp1[i][j][k]+a.s);
        chmax(dp1[i+1][j][k],dp1[i][j][k]);
    }
    rep(i,m) rep(j,m) rep(k,lim) {
        Artist a=artist2[i];
        int lim_n = k+a.e;
        if(lim_n <= lim&&dp2[i][j][k]!=-1) 
            chmax(dp2[i+1][j+1][lim_n],dp2[i][j][k]+a.s);
        chmax(dp2[i+1][j][k],dp2[i][j][k]);
    }

    //rep(i,20) printf("%d %d\n",i,dp1[n][2][i]);
    //rep(i,20) printf("%d %d\n",i,dp2[m][2][i]);

    int ans=0;
    rep(i,lim) {
        int max1=max(dp1[n][1][i],dp1[n][2][i]);
        int max2=0;
        for(int j=x;j<=m;j++) for(int k=0;k<=lim-i;k++) chmax(max2,dp2[m][j][k]);

        chmax(ans,max1+max2);
        // printf("%d %d : %d\n",i,lim-i,max1+max2);
    }

    cout<<ans<<endl;
}

int main() {
    while(cin>>lim>>n>>m>>x) {
        if(lim+n+m+x==0) break;
        solve();
    }
    return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 43968
final_rank: 18

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
char in[100];
int dp[110][1010];
int val[1010];
int sp[110];
int sq[110];
int np[110];
int nq[110];
int main(){
	int a,b,c,d;
	while(scanf("%d%d%d%d",&a,&b,&c,&d),a){
		for(int i=0;i<b;i++){
			scanf("%s%d%d",in,sp+i,sq+i);
		}
		for(int i=0;i<c;i++)scanf("%s%d%d",in,np+i,nq+i);
		for(int i=0;i<110;i++)for(int j=0;j<1010;j++)dp[i][j]=-99999999;
		dp[0][0]=0;
		for(int i=0;i<c;i++){
			for(int j=i;j>=0;j--){
				for(int k=a-np[i];k>=0;k--){
					dp[j+1][k+np[i]]=max(dp[j+1][k+np[i]],dp[j][k]+nq[i]);
				}
			}
		}
		for(int i=0;i<1010;i++)val[i]=-99999999;
		for(int i=d;i<=c;i++)for(int j=0;j<=a;j++)val[j]=max(val[j],dp[i][j]);
		int ret=0;
		for(int i=0;i<b;i++){
			for(int j=0;j<=a-sp[i];j++){
		//		if(sq[i]+val[j]==59)printf("%d %d\n",i,j);
				ret=max(ret,sq[i]+val[j]);
			}
			for(int j=i+1;j<b;j++){
				for(int k=0;k<=a-sp[i]-sp[j];k++){
			//		if(sq[i]+sq[j]+val[k]==59)printf("%d %d %d\n",i,j,k);
					ret=max(ret,sq[i]+sq[j]+val[k]);
				}
			}
		}
		printf("%d\n",ret);
	}
}
accuracy: 1
time_ms: 30
memory_kb: 1472
final_rank: 7

code_snippet: #include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <complex>
#include <string>
#include <sstream>
#include <algorithm>
#include <numeric>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <iostream>
#include <map>
#include <set>
using namespace std;
typedef pair<int,int> P;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define INF 2000000000
#define sz(x) ((int)(x).size())
#define fi first
#define sec second
#define SORT(x) sort((x).begin(),(x).end())
#define all(x) (x).begin(),(x).end()
#define EQ(a,b) (abs((a)-(b))<eps)
template<class T> void chmax(T& a,const T b){if(a<b)a=b;}
char name[105][40],sname[105][40];
int se[105],ss[105],e[105],s[105];
int dp[2][1005][3][105];
int Limit,N,M,X;
int main()
{
	while(1)
	{
		scanf("%d %d %d %d",&Limit,&N,&M,&X);
		if(Limit==0&&N==0&&M==0&&X==0)break;
		for(int i=0;i<N;i++)scanf("%s %d %d",sname[i],&se[i],&ss[i]);
		for(int i=0;i<M;i++)scanf("%s %d %d",name[i],&e[i],&s[i]);
		memset(dp,-1,sizeof(dp));
		dp[0][0][0][0]=0;
		int ans=0;
		for(int i=0;i<N+M;i++)
		{
			memset(dp[(i+1)%2],-1,sizeof(dp[(i+1)%2]));
			for(int j=0;j<=Limit;j++)
			{
				if(i<N)
				{
					for(int k=0;k<3;k++)
					{
						if(dp[i%2][j][k][0]==-1)continue;
						chmax(dp[(i+1)%2][j][k][0],dp[i%2][j][k][0]);
						if(j+se[i]>Limit||k>=2)continue;
						chmax(dp[(i+1)%2][j+se[i]][k+1][0],dp[i%2][j][k][0]+ss[i]);
					}
				}
				else
				{
					int idx=i-N;
					for(int k=1;k<3;k++)
					{
						for(int l=0;l<=M;l++)
						{
							if(dp[i%2][j][k][l]==-1)continue;
							chmax(dp[(i+1)%2][j][k][l],dp[i%2][j][k][l]);
							if(j+e[idx]>Limit||l>=M)continue;
							chmax(dp[(i+1)%2][j+e[idx]][k][l+1],dp[i%2][j][k][l]+s[idx]);
						}
					}
				}
			}
		}
		for(int j=0;j<=Limit;j++)
		{
			for(int k=1;k<3;k++)
			{
				for(int l=X;l<=M;l++)
				{
					chmax(ans,dp[(N+M)%2][j][k][l]);
				}
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 3680
final_rank: 13

code_snippet: #define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f
#include <cstdio>
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <limits>
#include <map>
#include <string>
#include <cstring>
#include <set>
#include <deque>
#include <bitset>
#include <list>
#include <cctype>
#include <utility>
 
using namespace std;
 
typedef long long ll;
typedef pair <int,int> P;
typedef pair <int,P > PP;
 
static const int tx[] = {0,1,0,-1};
static const int ty[] = {-1,0,1,0};
 
static const double EPS = 1e-8;

// dp[picked secret][picked standard][money] ::= max satisfaction
int dp[3][105][1005]; 

int main(){
  int money_limit;
  int total_secret_artists;
  int total_standard_artists;
  int to_pick_standard_artists;
  while(~scanf("%d %d %d %d",
               &money_limit,
               &total_secret_artists,
               &total_standard_artists,
               &to_pick_standard_artists)){
    
    if(money_limit == 0
       && total_secret_artists == 0
       && total_standard_artists == 0
       && to_pick_standard_artists == 0) break;

    memset(dp,-1,sizeof(dp));
    dp[0][0][0] = 0;
    for(int artist_idx=0;artist_idx<total_secret_artists;artist_idx++){
      string name;
      int cost;
      int satisfaction;

      cin >> name >> cost >> satisfaction;
      for(int prev_picked=1;prev_picked>=0;prev_picked--){
        for(int prev_money=1000;prev_money>=0;prev_money--){
          if(prev_money + cost > 1000) continue;

          if(dp[prev_picked][0][prev_money] == -1) continue;
          dp[prev_picked + 1][0][prev_money + cost]
            = max(dp[prev_picked][0][prev_money] + satisfaction,
                  dp[prev_picked + 1][0][prev_money + cost]);
        }
      }
    }
    for(int artist_idx=0;artist_idx<total_standard_artists;artist_idx++){
      string name;
      int cost;
      int satisfaction;
      cin >> name >> cost >> satisfaction;
      for(int picked_secret=min(2,total_secret_artists);picked_secret>=1;picked_secret--){
        for(int prev_picked_standard = artist_idx; prev_picked_standard  >= 0; prev_picked_standard--){
          for(int prev_money=1000;prev_money>=0;prev_money--){
          if(prev_money + cost > 1000) continue;

          if(dp[picked_secret][prev_picked_standard][prev_money] == -1) continue;
          dp[picked_secret][prev_picked_standard + 1][prev_money + cost]
            = max(dp[picked_secret][prev_picked_standard + 1][prev_money + cost],
                  dp[picked_secret][prev_picked_standard][prev_money] + satisfaction);
          }

        }
      }        
    }

    int res = 0;
    for(int picked_secret=min(2,total_secret_artists);picked_secret>=1;picked_secret--){
      for(int picked_standard = total_standard_artists; picked_standard  >=to_pick_standard_artists; picked_standard--){
        for(int money=money_limit;money>=0;money--){
          res = max(dp[picked_secret][picked_standard][money],res);
        }
      }
    }

    printf("%d\n",res);
  }
}
accuracy: 1
time_ms: 40
memory_kb: 2496
final_rank: 11

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>	// require sort next_permutation count __gcd reverse etc.
#include <cstdlib>	// require abs exit atof atoi 
#include <cstdio>		// require scanf printf
#include <functional>
#include <numeric>	// require accumulate
#include <cmath>		// require fabs
#include <climits>
#include <limits>
#include <cfloat>
#include <iomanip>	// require setw
#include <sstream>	// require stringstream 
#include <cstring>	// require memset
#include <cctype>		// require tolower, toupper
#include <fstream>	// require freopen
#include <ctime>		// require srand
#define rep(i,n) for(int i=0;i<(n);i++)
#define ALL(A) A.begin(), A.end()
#define INF 1<<29
#define DEBUG 0
/*
	Ritsumeikan University Programming Contest 2011 , Japan, 2011-10-05

	2285 - Anipero

	Anipero01.cpp
	まずは全探索.

	Anipero02.cpp
	メモ化再帰

	Anipero03.cpp
	DPに書き直す

	Anipero04.cpp
	ループの向きを反対にする

*/
using namespace std;

typedef long long ll;
typedef pair<int, int> P;

const int MAX_LIMIT = 1000;
const int MAX_N = 100;
const int MAX_M = 100;

int LIMIT, N, M, X;

int sec_e[MAX_N+1], sec_s[MAX_N+1], e[MAX_M+1], s[MAX_M+1];

int dp[MAX_M+1][MAX_LIMIT+1];
/*
int dfs (int depth, int cnt, int cost ){
	if (cost > LIMIT ) return -INF;
	if (depth >= M ){
		return 0;
	} // end if
	if (memo[depth][cnt][cost] != -1 ) return memo[depth][cnt][cost];

	int res = -INF;
	res = max (res, dfs (depth + 1, cnt, cost ) );
	res = max (res, dfs (depth + 1, cnt + 1, cost + e[depth] ) + s[depth] );

	return memo[depth][cnt][cost] = res;
}
*/

int solve (void ){
	rep (j, MAX_M+1 ) rep (k, MAX_LIMIT + 1 ) dp[j][k] = -INF;
	dp[0][0] = 0;

	rep (i, M ){
		for (int j = i; j >= 0; j-- ){
			for (int k = 0; k <= LIMIT; k++ ){
				if (k + e[i] <= LIMIT ){
					dp[j+1][k+e[i]] = max (dp[j+1][k+e[i]], dp[j][k]+s[i] );
					dp[j][k+e[i]] = max (dp[j][k+e[i]], dp[j][k] );
				} // end if
			} // end for
		} // end for
	} // end for

#if DEBUG
	rep (i, M+1 ){
		for (int j = 0; j <= LIMIT; j++ ){
			cerr << (dp[i][j] <= -INF/2 ? -1 : dp[i][j] ) << (j != LIMIT ? ' ' : '\n' );
		} // end for
	} // end rep
#endif

	int res = 0;
	for (int j = X; j <= M; j++ )
	rep (k, LIMIT+1 ){
		if (dp[j][k] >= 0  ){
			int curr = -INF;
			rep (ii, N ){
				if (k + sec_e[ii] <= LIMIT )
					curr = max (curr, sec_s[ii] );
				rep (jj, ii )
					if (k + sec_e[ii] + sec_e[jj] <= LIMIT )
						curr = max (curr, sec_s[ii] + sec_s[jj] );
			} // end rep
			res = max (res, dp[j][k] + curr );
		} // end if
	} // end rep
	
	return res;
}

int main()
{
	ios_base::sync_with_stdio(0);
	while (cin >> LIMIT >> N >> M >> X, LIMIT ){
		memset (sec_e, 0, sizeof (sec_e ) );
		memset (sec_s, 0, sizeof (sec_s ) );
		memset (e, 0, sizeof (e ) );
		memset (s, 0, sizeof (s ) );
		string str;
		rep (i, N ) cin >> str >> sec_e[i] >> sec_s[i];
		rep (j, M ) cin >> str >> e[j] >> s[j];
		int res = solve() ;
		cout << res << endl;
	} // end while	
		
	return 0;
}
accuracy: 1
time_ms: 250
memory_kb: 1612
final_rank: 14

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

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define IINF (INT_MAX)
#define MAX_LIMIT 1100
#define MAX 110

using namespace std;

int pre[MAX_LIMIT][3],pre2[MAX_LIMIT][MAX],LIMIT,N,M,X,SEC_E[MAX],SEC_S[MAX],E[MAX],S[MAX];
string tmp;


int main(){
  while(cin >> LIMIT >> N >> M >> X, LIMIT|N|M|X){
    rep(i,N)cin >> tmp >> SEC_E[i] >> SEC_S[i];
    rep(i,M)cin >> tmp >> E[i] >> S[i];
    rep(i,LIMIT+1)rep(j,3)pre[i][j] = -1;
    rep(i,LIMIT+1)rep(j,MAX)pre2[i][j] = -1;
    pre[0][0] = pre2[0][0] = 0;

    rep(i,N)for(int j=1;j>=0;j--)rep(k,LIMIT+1){
	if( pre[k][j] == -1 ) continue;
	int total_money = k + SEC_E[i];
	if( total_money > LIMIT ) continue;
	pre[total_money][j+1] = max(pre[total_money][j+1],pre[k][j]+SEC_S[i]);
      }

    rep(i,3)rep(j,LIMIT+1)if( j ) pre[j][i] = max(pre[j][i],pre[j-1][i]);

    rep(i,M)for(int j=M-1;j>=0;j--)rep(k,LIMIT+1){
	if( pre2[k][j] == -1 ) continue;
	int total_money = k + E[i];
	if( total_money > LIMIT ) continue;
	pre2[total_money][j+1] = max(pre2[total_money][j+1],pre2[k][j]+S[i]);
      }

    rep(i,M+1)rep(j,LIMIT+1)if( j ) pre2[j][i] = max(pre2[j][i],pre2[j-1][i]);

    int ans = 0;

    REP(i,X,M+1)REP(j,1,3)rep(k,LIMIT+1){
      if( pre2[k][i] == -1 || pre[LIMIT-k][j] == -1 ) continue;
      int points = pre2[k][i] + pre[LIMIT-k][j];
      ans = max(ans,points);
    }

    cout << ans << endl;

  }
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 1648
final_rank: 9