import sys
# 再帰回数のカウント用グローバル変数
call_count = 0
class Job:
def __init__(self, start, end, weight):
self.start = start
self.end = end
self.weight = weight
def solve():
# 入力の読み込み
try:
line1 = sys.stdin.readline()
if not line1: return
n = int(line1.strip())
except EOFError:
return
jobs = []
for _ in range(n):
s, e, w = map(int, sys.stdin.readline().split())
jobs.append(Job(s, e, w))
# 1. 終了時刻でソート (これがアルゴリズムの前提)
jobs.sort(key=lambda x: x.end)
# 2. p(j) の計算: ジョブjと衝突しない、直前のジョブのインデックス
# p[j] は jobs[j-1] と両立する最大のインデックス (1-indexed)
p = [0] * (n + 1)
for j in range(1, n + 1):
for i in range(j - 1, 0, -1):
if jobs[i-1].end <= jobs[j-1].start:
p[j] = i
break
# --- 通常の再帰 ---
global call_count
call_count = 0
def compute_opt(j):
global call_count
call_count += 1
if j == 0:
return 0
# 課題の指示通り OPT(n-1) を先に呼び出し、次に OPT(p(n)) を呼び出す
res_exclude = compute_opt(j - 1)
res_include = jobs[j-1].weight + compute_opt(p[j])
return max(res_exclude, res_include)
ans_rec = compute_opt(n)
print(f"opt: {ans_rec}")
print(f"calls: {call_count}")
# --- メモ化再帰 ---
call_count = 0
memo = [-1] * (n + 1)
def m_compute_opt(j):
global call_count
call_count += 1
if j == 0:
return 0
if memo[j] != -1:
return memo[j]
# 指示通り OPT(j-1) -> OPT(p(j)) の順で評価
res_exclude = m_compute_opt(j - 1)
res_include = jobs[j-1].weight + m_compute_opt(p[j])
memo[j] = max(res_exclude, res_include)
return memo[j]
ans_memo = m_compute_opt(n)
print(f"opt: {ans_memo}")
print(f"calls: {call_count}")
if __name__ == "__main__":
solve()
aW1wb3J0IHN5cwoKIyDlho3luLDlm57mlbDjga7jgqvjgqbjg7Pjg4jnlKjjgrDjg63jg7zjg5Djg6vlpInmlbAKY2FsbF9jb3VudCA9IDAKCmNsYXNzIEpvYjoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBzdGFydCwgZW5kLCB3ZWlnaHQpOgogICAgICAgIHNlbGYuc3RhcnQgPSBzdGFydAogICAgICAgIHNlbGYuZW5kID0gZW5kCiAgICAgICAgc2VsZi53ZWlnaHQgPSB3ZWlnaHQKCmRlZiBzb2x2ZSgpOgogICAgIyDlhaXlipvjga7oqq3jgb/ovrzjgb8KICAgIHRyeToKICAgICAgICBsaW5lMSA9IHN5cy5zdGRpbi5yZWFkbGluZSgpCiAgICAgICAgaWYgbm90IGxpbmUxOiByZXR1cm4KICAgICAgICBuID0gaW50KGxpbmUxLnN0cmlwKCkpCiAgICBleGNlcHQgRU9GRXJyb3I6CiAgICAgICAgcmV0dXJuCgogICAgam9icyA9IFtdCiAgICBmb3IgXyBpbiByYW5nZShuKToKICAgICAgICBzLCBlLCB3ID0gbWFwKGludCwgc3lzLnN0ZGluLnJlYWRsaW5lKCkuc3BsaXQoKSkKICAgICAgICBqb2JzLmFwcGVuZChKb2IocywgZSwgdykpCgogICAgIyAxLiDntYLkuobmmYLliLvjgafjgr3jg7zjg4ggKOOBk+OCjOOBjOOCouODq+OCtOODquOCuuODoOOBruWJjeaPkCkKICAgIGpvYnMuc29ydChrZXk9bGFtYmRhIHg6IHguZW5kKQoKICAgICMgMi4gcChqKSDjga7oqIjnrpc6IOOCuOODp+ODlmrjgajooZ3nqoHjgZfjgarjgYTjgIHnm7TliY3jga7jgrjjg6fjg5bjga7jgqTjg7Pjg4fjg4Pjgq/jgrkKICAgICMgcFtqXSDjga8gam9ic1tqLTFdIOOBqOS4oeeri+OBmeOCi+acgOWkp+OBruOCpOODs+ODh+ODg+OCr+OCuSAoMS1pbmRleGVkKQogICAgcCA9IFswXSAqIChuICsgMSkKICAgIGZvciBqIGluIHJhbmdlKDEsIG4gKyAxKToKICAgICAgICBmb3IgaSBpbiByYW5nZShqIC0gMSwgMCwgLTEpOgogICAgICAgICAgICBpZiBqb2JzW2ktMV0uZW5kIDw9IGpvYnNbai0xXS5zdGFydDoKICAgICAgICAgICAgICAgIHBbal0gPSBpCiAgICAgICAgICAgICAgICBicmVhawoKICAgICMgLS0tIOmAmuW4uOOBruWGjeW4sCAtLS0KICAgIGdsb2JhbCBjYWxsX2NvdW50CiAgICBjYWxsX2NvdW50ID0gMAogICAgCiAgICBkZWYgY29tcHV0ZV9vcHQoaik6CiAgICAgICAgZ2xvYmFsIGNhbGxfY291bnQKICAgICAgICBjYWxsX2NvdW50ICs9IDEKICAgICAgICBpZiBqID09IDA6CiAgICAgICAgICAgIHJldHVybiAwCiAgICAgICAgIyDoqrLpoYzjga7mjIfnpLrpgJrjgoogT1BUKG4tMSkg44KS5YWI44Gr5ZG844Gz5Ye644GX44CB5qyh44GrIE9QVChwKG4pKSDjgpLlkbzjgbPlh7rjgZkKICAgICAgICByZXNfZXhjbHVkZSA9IGNvbXB1dGVfb3B0KGogLSAxKQogICAgICAgIHJlc19pbmNsdWRlID0gam9ic1tqLTFdLndlaWdodCArIGNvbXB1dGVfb3B0KHBbal0pCiAgICAgICAgcmV0dXJuIG1heChyZXNfZXhjbHVkZSwgcmVzX2luY2x1ZGUpCgogICAgYW5zX3JlYyA9IGNvbXB1dGVfb3B0KG4pCiAgICBwcmludChmIm9wdDoge2Fuc19yZWN9IikKICAgIHByaW50KGYiY2FsbHM6IHtjYWxsX2NvdW50fSIpCgogICAgIyAtLS0g44Oh44Oi5YyW5YaN5biwIC0tLQogICAgY2FsbF9jb3VudCA9IDAKICAgIG1lbW8gPSBbLTFdICogKG4gKyAxKQoKICAgIGRlZiBtX2NvbXB1dGVfb3B0KGopOgogICAgICAgIGdsb2JhbCBjYWxsX2NvdW50CiAgICAgICAgY2FsbF9jb3VudCArPSAxCiAgICAgICAgaWYgaiA9PSAwOgogICAgICAgICAgICByZXR1cm4gMAogICAgICAgIGlmIG1lbW9bal0gIT0gLTE6CiAgICAgICAgICAgIHJldHVybiBtZW1vW2pdCiAgICAgICAgCiAgICAgICAgIyDmjIfnpLrpgJrjgoogT1BUKGotMSkgLT4gT1BUKHAoaikpIOOBrumghuOBp+ipleS+oQogICAgICAgIHJlc19leGNsdWRlID0gbV9jb21wdXRlX29wdChqIC0gMSkKICAgICAgICByZXNfaW5jbHVkZSA9IGpvYnNbai0xXS53ZWlnaHQgKyBtX2NvbXB1dGVfb3B0KHBbal0pCiAgICAgICAgCiAgICAgICAgbWVtb1tqXSA9IG1heChyZXNfZXhjbHVkZSwgcmVzX2luY2x1ZGUpCiAgICAgICAgcmV0dXJuIG1lbW9bal0KCiAgICBhbnNfbWVtbyA9IG1fY29tcHV0ZV9vcHQobikKICAgIHByaW50KGYib3B0OiB7YW5zX21lbW99IikKICAgIHByaW50KGYiY2FsbHM6IHtjYWxsX2NvdW50fSIpCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgc29sdmUoKQ==