Problem:


Score : 400 points

Problem Statement

Find the largest integer that can be formed with exactly N matchsticks, under the following conditions:

Every digit in the integer must be one of the digits A_1, A_2, ..., A_M (1 \leq A_i \leq 9).

The number of matchsticks used to form digits 1, 2, 3, 4, 5, 6, 7, 8, 9 should be 2, 5, 5, 4, 5, 6, 3, 7, 6, respectively.

Constraints

All values in input are integers.

2 \leq N \leq 10^4

1 \leq M \leq 9

1 \leq A_i \leq 9

A_i are all different.

There exists an integer that can be formed by exactly N matchsticks under the conditions.

Input

Input is given from Standard Input in the following format:

N M
A_1 A_2 ... A_M

Output

Print the largest integer that can be formed with exactly N matchsticks under the conditions in the problem statement.

Sample Input 1

20 4
3 7 8 4

Sample Output 1

777773

The integer 777773 can be formed with 3 + 3 + 3 + 3 + 3 + 5 = 20 matchsticks, and this is the largest integer that can be formed by 20 matchsticks under the conditions.

Sample Input 2

101 9
9 8 7 6 5 4 3 2 1

Sample Output 2

71111111111111111111111111111111111111111111111111

The output may not fit into a 64-bit integer type.

Sample Input 3

15 3
5 4 6

Sample Output 3

654



Sample input:
20 4
3 7 8 4


Sample output:
777773

Submission status: Accepted

Solution code:
N, M = map(int, input().split())  # N本のマッチ棒, M種類の数字
A = list(map(int, input().split()))  # 使える数字の配列A0 ~ Am
A.sort()
A.reverse()


def num(a):  # sticks[A[i] - 1]でA[i]にに必要なマッチの本数
    return [2, 5, 5, 4, 5, 6, 3, 7, 6][a - 1]


dp = [0] * (N + 1)  # dp[N] = 桁数
for i in range(1, N + 1):
    match_match = [dp[i - num(a)] + 1 for a in A if i - num(a) >= 0]
    if match_match:
        dp[i] = max(match_match)
    else:
        dp[i] = -1000

remind = 0  # 消費したマッチ棒の数
ans = ''  # answer
for i in range(dp[N]):
    for a in A:
        if N - num(a) - remind >= 0:
            if dp[N - num(a) - remind] == dp[N] - 1 - i:
                remind += num(a)
                ans += str(a)
                break
print(ans)

Submission status: Accepted

Solution code:
def f(x):
    k = int(x)
    return c[k], k


c = [0, 2, 5, 5, 4, 5, 6, 3, 7, 6]
N, M = list(map(int, input().split()))
A = list(map(f, input().split()))
A = sorted(A, key=lambda x: x[0] * 10 - x[1])

# 数字を作成するのに必要なマッチ数のリストを作成
b = []
dic = {}
n = 0
for d in A:
    if n != d[0]:
        b.append(d[0])
        n = d[0]
        dic[n] = d[1]

ans = [0] * b[0]
n = b[0]
while True:
    max_ = 0
    for d in b:
        if n - d == 0:
            if dic[d] > max_:
                max_ = dic[d]
        elif n - d > 0 and ans[n - d] > 0:
            t = ans[n - d] * 10 + dic[d]
            max_ = max(max_, t)

    if n == N:
        print(max_)
        break
    ans.append(max_)
    n += 1

Submission status: Accepted

Solution code:
nums = [2,5,5,4,5,6,3,7,6]

n,m = map(int,input().split())

digits = list(map(int,input().split()))

dp = [-1]*(n+10)
dp[0] = 0
for i in range(n+1):
   if(dp[i] == -1):
       continue
   else:
       for digit in digits:
           dp[i+nums[digit-1]] = max(dp[i+nums[digit-1]], dp[i]*10+digit)
           

print(dp[n])

Submission status: Accepted

Solution code:
n,m = map(int,input().split())
match = [2,5,5,4,5,6,3,7,6]
a = [int(i) for i in input().split()]

dp = [0]+[-1]*(n+1)

for i in range(1,n+1):
  for j in a:
    honsu = match[j-1]
    if i-honsu>=0:
      dp[i] = max(dp[i-honsu]*10+j,dp[i])
print(dp[n])

Submission status: Accepted

Solution code:
def printing(a_start, a_2, n):

    a_3 = []
    mod_list = []
    for i in range(len(a_2)):
        if a_2[i][1] % a_start[1] not in mod_list and a_2[i][1] % a_start[1] != 0:
            a_3.append(a_2[i])
            mod_list.append(a_2[i][1] % a_start[1])
    a_3.sort(key=lambda x: x[1], reverse=True)


    if len(a_3) >= 2:
        if a_start[0] + a_3[-1][0] < n and a_3[0][0] < a_3[1][0] and a_3[1][0] > a_start[0]:
            a_3.pop(0)


    ans = ""
    while n % a_start[1] != 0:
        for i in range(len(a_3)):
            if n % a_start[1] >= a_3[i][1] % a_start[1]:
                n -= a_3[i][1]
                ans += str(a_3[i][0])
                break
            elif n % a_start[1] == 0:
                break
        else:
            n -= a_3[0][1]
            ans += str(a_3[0][0])

    ans = ans + str(a_start[0]) * (n // a_start[1])
    ans_list = sorted([ans[i] for i in range(len(ans))], reverse=True)
    print("".join(ans_list))

def main():
    n, m = [int(i) for i in input().split()]
    a = sorted([int(i) for i in input().split()], reverse=True)
    number = [0, 2, 5, 5, 4, 5, 6, 3, 7, 6]
    a_list = []
    a_2 = []

    for i in range(m):
        if number[a[i]] not in a_list:
            a_2.append([a[i], number[a[i]]])
            a_list.append(number[a[i]])
    a_2.sort(key=lambda x: x[1])
    a_start = a_2.pop(0)
    printing(a_start, a_2, n)

main()

Submission status: Accepted

Solution code:
import sys

sys.setrecursionlimit(10000)

from collections import Counter
 
def parse_line(line, type=int):
    return [type(x) for x in line.split(' ')]
 
 
#              1, 2, 3, 4, 5, 6, 7, 8, 9
weight = ['x', 2, 5, 5, 4, 5, 6, 3, 7, 6]
 

def run(k, weight_to_num, cache):
    if k not in cache:
        if k <= 1:
            res = 0
        else:
            res = 0
            for w, num in weight_to_num.items():
                res = max(res, run(k - w, weight_to_num, cache))
            if res > 0:
                res += 1
            if k in weight_to_num:
                res = max(1, res)
        cache[k] = res
    return cache[k]
 
 
def main():
    n, m = parse_line(input())
    numbers = set(parse_line(input()))
    #numbers = [6, 8, 9]
 
    #for n in range(2, 60):
 
    if 6 in numbers and 9 in numbers:
        numbers.remove(6)
    if 2 in numbers and 3 in numbers:
        numbers.remove(2)
    if 2 in numbers and 5 in numbers:
        numbers.remove(2)
    if 3 in numbers and 5 in numbers:
        numbers.remove(3)
 
    weight_to_num = {weight[v]: v for v in numbers}
    cache = {}
    run(n, weight_to_num, cache)
    #print(cache)
    #return
 
    ws = list(weight_to_num.keys())
    ws.sort(reverse=True, key=lambda w: weight_to_num[w])
    res = []
    cache = {k:v for k,v in cache.items() if v > 0}
    cache[0] = 0
 
    if n not in cache:
        return
 
    l = cache[n]
    while l:
        for w in ws:
            if cache.get(n - w, 'False') == l - 1:
                res.append(weight_to_num[w])
                n = n - w
                l -= 1
                break
    print(''.join((str(x) for x in res)))
 
 
if __name__ == '__main__':
    main()

# 20 4
# 3 7 8 4

Submission status: Accepted

Solution code:
def get_int(): return int(input())
def get_float(): return float(input())
def get_line(): return input().split()
def get_lines(v): return [get_line() for _ in range(v)]
def get_int_line(): return list(map(int, get_line()))
def get_int_lines(v): return [get_int_line() for _ in range(v)]
def get_float_line(): return list(map(float, get_line()))
def get_float_lines(v): return [get_float_line() for _ in range(v)]

cost = [0,2,5,5,4,5,6,3,7,6]
N, M = get_int_line()
A = get_int_line()

dp = [-1 for _ in range(N + 1)]
dp[0] = 0
for i in range(N):
  if (dp[i] == -1): continue
  for v in A:
    if (i + cost[v] <= N and dp[i + cost[v]] < dp[i] * 10 + v):
      dp[i + cost[v]] = dp[i] * 10 + v

print(dp[N])

Submission status: Accepted

Solution code:
match = [2,5,5,4,5,6,3,7,6]
n,m=map(int,input().split())
aa=list(map(int,input().split()))
dp=[-1]*(n+10)

dp[0]=0
for i in range(n+1):
        for nums in aa:
                if dp[i] == -1 :continue
                dp[i+match[nums-1]] = max(dp[i]*10+nums,dp[i+match[nums-1]])

print(dp[n])

Submission status: Accepted

Solution code:

# coding: utf-8

# In[1]:


def main():
    N,M = map(int, input().split())
    A = list(map(int, input().split()))
    
    match = [0, 2, 5, 5, 4, 5, 6, 3, 7, 6]
    
    result = [-1 for _ in range(N+1)]
    result[0] = 0
    
    #print(result)
    
    for i in range(1, N+1):
        for a in A:
            if i < match[a]:
                #print(i,a,result)
                continue
            result[i] = max(result[i], result[i-match[a]]*10+a)
            #print(i,a,result)
    
    print(result[N])


# In[2]:


main()

Submission status: Accepted

Solution code:
n, m = map(int, input().split())
a = [int(a) for a in input().split()]    
required_matches = {
    1: 2,
    2: 5,
    3: 5,
    4: 4,
    5: 5,
    6: 6,
    7: 3,
    8: 7,
    9: 6
}

dp = [0] + [-1] * n
for used_matches in range(1, n+1):
    usable_digits = [ai for ai in a if used_matches - required_matches[ai] >= 0]
    if usable_digits != []:
        dp[used_matches] = max([dp[used_matches-required_matches[ai]]*10 + ai
            for ai in usable_digits])
print(dp[n])

Submission status: Accepted

Solution code:
INF = 10**10
arr = [INF,2,5,5,4,5,6,3,7,6]
N,M = map(int,input().split())
src = sorted(list(map(int,input().split())))

dp = [-INF]*(N+1)
dp[0] = 0
for i in range(N):
    for j in src:
        if i + arr[j] <= N:
            dp[i + arr[j]] = max(dp[i + arr[j]], dp[i] + 1)
ans = ''
while(N>0):
    for i in src[::-1]:
        if N - arr[i] >= 0 and dp[N-arr[i]] == dp[N] - 1:
            ans += str(i)
            N -= arr[i]
            break
print(ans if ans else 0)

Submission status: Accepted

Solution code:
def chmax(x, y):
    if x == '-':
        return y

    lx = len(x)
    ly = len(y)
    if lx < ly:
        return y
    elif lx == ly:
        if x < y: return y
        else: return x
    else:
        return x


N, M = map(int, input().split())
a = list(map(int, input().split()))

cnt = [N + 1, 2, 5, 5, 4, 5, 6, 3, 7, 6]
dp = ['-' for _ in range(N + 10 + 1)]
dp[0] = ''
# dp[j]: j 本使ってできる最大の数

for i in range(N + 1):
    # print(dp)
    if dp[i] == '-': continue
    for aa in a:
        dp[i + cnt[aa]] = chmax(dp[i + cnt[aa]], dp[i] + str(aa))

print(dp[N])

Submission status: Accepted

Solution code:
#ABC118D-MatchMatching.py

import sys
from functools import lru_cache

sys.setrecursionlimit(10000)

input = sys.stdin.readline

N, M = list(map(int, input().split()))

A = list(map(int, input().split()))
A.sort(reverse=True)

B = [2,5,5,4,5,6,3,7,6]

def num(n):
    return B[n-1]

@lru_cache(maxsize=None)
def dp(i):
    if i == 0:
        return 0
    elif i < 0:
        return -float('inf')
    else:
        C = []
        for j in range(M):
            C.append(dp(i-num(A[j]))+1)
        return max(C)

s = ''
n = dp(N)
K = N

for i in range(n):
    for j in range(M):
        if dp(K-num(A[j])) == dp(K)-1:
            s += str(A[j])
            K -= B[A[j]-1]
            break

print(int(s))

Submission status: Accepted

Solution code:
# https://atcoder.jp/contests/abc118/tasks/abc118_d


def main():
    N, M = map(int, input().split())

    A = list(map(int, input().split()))  # 使っていい数字

    costs = [0, 2, 5, 5, 4, 5, 6, 3, 7, 6]  # 各数字のマッチの数

    dp = [-1 for _ in range(N + 1)]
    dp[0] = 0
    for i in range(1, N + 1):
        for a in A:
            if i < costs[a]:
                continue
            dp[i] = max(dp[i], dp[i - costs[a]] * 10 + a)
    print(dp[N])


main()

Submission status: Accepted

Solution code:
c=[0,2,5,5,4,5,6,3,7,6]
N,M=map(int, input().split())
A=list(map(int, input().split()))
INF=100010
dp = [-INF for _ in range(N+1)]
dp[0]=0

for i in range(N+1):
  for a in A:
    if i-c[a]>=0:
      dp[i]=max(dp[i],(dp[i-c[a]])*10+a)

print(dp[N])

Submission status: Accepted

Solution code:
costs = [2, 5, 5, 4, 5, 6, 3, 7, 6]


def main():
    N, M = map(int, input().split())
    A = list(map(int, input().split()))
    dp = [-1 for _ in range(N + 1)]
    dp[0] = 0
    for i in range(1, N + 1):
        for a in A:
            if i < costs[a - 1]:
                continue
            dp[i] = max(dp[i], dp[i - costs[a - 1]] * 10 + a)
    print(dp[N])


main()

Submission status: Accepted

Solution code:
import sys

def main():
  input = sys.stdin.readline
  N, M = map(int, input().split())
  A = list(map(int, input().split()))
  d = {1: 2, 2: 5, 3: 5, 4: 4, 5: 5, 6: 6, 7: 3, 8: 7, 9: 6}
  
  dp = [0 for _ in range(N+1)]
  for i in range(1, N+1):
    dpi = - float('inf')
    for a in A:
      if d[a] <= i:
        dpi = max(dpi, dp[i - d[a]] + 1)
    dp[i] = dpi

  ans = [0 for _ in range(dp[N])]
  for i in range(len(ans)):
    num = 0
    for a in A:
      if (d[a] <= N) and (dp[N - d[a]] == dp[N] - 1):
        num = max(num, a)
    ans[i] = str(num)
    N -= d[num]

  print(''.join(ans))


if __name__ == '__main__':
  main()

Submission status: Accepted

Solution code:
# -*- coding: utf-8 -*-
from sys import stdin
import numpy as np
from itertools import product

s_in = lambda: stdin.readline()[:-1]  # s = s_in()
d_in = lambda: int(stdin.readline())  # N = d_in()
ds_in = lambda: list(map(int, stdin.readline().split()))  # List = ds_in()


COST = np.array([2, 5, 5, 4, 5, 6, 3, 7, 6])

N, M = ds_in()
A_list = np.array(ds_in())
A_cost = COST[A_list - 1]  # 0始まりで取得

min_cost = min(A_cost)
base_num = max(A_list[A_cost == min_cost])

if N % min_cost == 0:
    print(int(str(base_num) * (N//min_cost)))
    exit()

# 本数をmin_costのmodを考え、cost最小のものを記憶
mod_cost = {i: [-1, 10**6] for i in range(1, min_cost)}
for a, c in zip(A_list, A_cost):
    mod = c % min_cost
    if mod > 0:
        if c < mod_cost[mod][1]:
            mod_cost[mod][1] = c
            mod_cost[mod][0] = a
        elif c == mod_cost[mod][1]:
            mod_cost[mod][0] = max(a, mod_cost[mod][0])

# 存在しないmodは除く
for i in range(1, min_cost):
    if mod_cost[i][1] > 10:
        del mod_cost[i]

N_mod = N % min_cost
upper = []
for m in mod_cost.keys():
    upper.append([i for i in range(0, min_cost + 1)])


ans = []
for cand in product(*upper):
    if N_mod == sum(map(lambda x, y: x*y, mod_cost.keys(), cand)) % min_cost:
        temp_N = N
        num_list = []
        for x, y in zip(mod_cost.keys(), cand):
            num_list.extend([mod_cost[x][0]] * y)
            temp_N -= mod_cost[x][1] * y
        if temp_N >= 0:
            num_list.extend([base_num] * (temp_N // min_cost))
            num_list.sort()
            ans.append(int(''.join(map(str, num_list[::-1]))))

print(max(ans))

Submission status: Accepted

Solution code:
match_num=[0,2,5,5,4,5,6,3,7,6]
N,M=map(int, input().split())
nums=sorted(list(map(int, input().split())),reverse=True)
INF=1000000
#max桁数
dp = [-INF for _ in range(N+1)]
dp[0]=0
usables=[]
for n in nums:
  usables.append(match_num[n])

for i in range(min(usables), N+1):
  tmp=[]
  for u in usables:
    if (i-u)>=0:
      tmp.append(dp[i-u])
  
  dp[i]=max(tmp)+1

remained_maches=N

ans=''  
for i in range(dp[N]):
  for j in range(M):
    if (remained_maches-usables[j])>=0:
      if dp[remained_maches]-1==dp[remained_maches-usables[j]]:
        ans+=str(nums[j])
        remained_maches-=usables[j]
        break
        
print(ans)

Submission status: Accepted

Solution code:
# -*- coding: utf-8 -*-

import math
import sys
from operator import itemgetter
input = sys.stdin.readline

# a = int(input().rstrip())
# a, b = map(int, input().rstrip().split())
# D = list(map(int, input().rstrip().split()))
# H = [int(input().rstrip()) for _ in range(L)]
# DD = [[0 for j in range(100)] for i in range(200)]
# dict = {} ## dictionary

# a = sorted(a, key=lambda x: x[1]))
# if __name__ == '__main__':

N, M = map(int, input().rstrip().split())
Ar = list(map(int, input().rstrip().split()))

def chmax(a, b):
	if a is None:
		return b
	elif len(a) < len(b):
		return b
	elif len(a) > len(b):
		return a
	else:
		return max(a, b)

dict = {}
num = [0, 2, 5, 5, 4, 5, 6, 3, 7, 6]
dp = [None] * (N+1)

for i in Ar:
	if num[i] in dict:
		dict[num[i]] = max(i, dict[num[i]])
	else:
		dict[num[i]] = i

# dp探索
dp[0] = ""
for i in range(1, N+1):
	for j in dict:
		if (i >= j) and (dp[i-j] is not None):
			dp[i] = chmax(dp[i], dp[i-j] + str(dict[j]))

print(dp[N])

Submission status: Accepted

Solution code:
import numpy as np

(N,M) = map(int,input().split())
A = list(map(int,input().split()))
costs = [0,2,5,5,4,5,6,3,7,6]

match = [-1]*(N+1)
match[0] = 0
for i in range(1,N+1):
  for a in A:
    if i < costs[a]:
      continue
    else:
      match[i] = max(match[i],match[i-costs[a]]*10+a)

print(match[N])

Submission status: Accepted

Solution code:
d = {1:2,2:5,3:5,4:4,5:5,6:6,7:3,8:7,9:6}
N,M = map(int,input().split())
A = list(map(int,input().split()))
A.sort()
d_ = {}
for i in range(M):
    d_[d[A[i]]] = A[i]
diff = [(d_[key],key) for key in d_]
diff.sort()

DP = ['']*(10**4+1)
for a,l in diff:
    DP[l] = str(a)
    
for i in range(N+1):
    for a,l in diff:
        if i-l >= 0:
            if len(DP[i-l])+1>=len(DP[i]) and DP[i-l]!='':
                    DP[i] = str(a)+DP[i-l]

ans = list(DP[N])
ans.sort()
ans.reverse()
ans = ''.join(ans)
print(ans)

Submission status: Accepted

Solution code:
"""
Match Matching
提出 #4299735 を参考に作成
"""


def solve():
	# 初期値の設定
	num = [0, 2, 5, 5, 4, 5, 6, 3, 7, 6]
	N, M = map(int, input().split())
	A = [int(i) for i in input().split()]
	A.sort(reverse=True)
	# 丁度n本で作成できる最大桁数を格納する.
	# 初期値は -inf (丁度使い切ることは不可能) としておく
	dp = [-1 * float("inf")] * (N + 1)

	# 動的計画法で丁度n本のマッチを使うときに作れる最大桁数を計算する
	dp[0] = 0
	for n in range(1, N + 1):
		for a in A:
			if n - num[a] >= 0:
				# マッチがnum[a]本あるときにaが作れるなら,
				# n - num[a]本の時よりも1桁多く作れるはず.
				# これをすべてのAに対して行い、その中で最大となった桁数を求める.
				dp[n] = max(dp[n], dp[n - num[a]] + 1)

	# 回答となる数値を算出
	ans = ''
	for i in range(dp[N]):  # dp[N]桁の数を上位の桁から決定していく
		for a in A:
			# num[a]本使って数を作ったとき,
			# N - num[a] 本で作れる桁数よりも N 本で作れる桁数のほうが1多い場合,
			# numを作っても最終的に作れる数の桁数は変わらない.
			# そのため dp[N] - 1 == dp[N - num[a]] を満たすような最大のAを作り,
			# 作成する数の上位桁に使用すればよい.
			# 同じ本数のマッチを使用する場合はより大きい数を採用する.
			# そのためAはあらかじめ降順にソートしておく.
			# 最初の条件で配列外アクセスを防ぐ
			if N - num[a] > -1 and dp[N] - 1 == dp[N - num[a]]:
				ans += str(a)
				N -= num[a]
				break
		# print('現在の残本数', N, '採用された数', a)

	print(ans)


if __name__ == '__main__':
	solve()

Submission status: Accepted

Solution code:
"""
Match Matching
提出 #4299735 を参考に作成
"""


def solve():
    # 初期値の設定
    num = [0, 2, 5, 5, 4, 5, 6, 3, 7, 6]
    N, M = map(int, input().split())
    A = [int(i) for i in input().split()]
    A.sort(reverse=True)
    # 丁度n本で作成できる最大桁数を格納する.
    # 初期値は -inf (丁度使い切ることは不可能) としておく
    dp = [-1 * float("inf")] * (N + 1)

    # 動的計画法で丁度n本のマッチを使うときに作れる最大桁数を計算する
    dp[0] = 0
    for n in range(1, N + 1):
        for a in A:
            if n - num[a] >= 0:
                # マッチがnum[a]本あるときにaが作れるなら,
                # n - num[a]本の時よりも1桁多く作れるはず.
                # これをすべてのAに対して行い、その中で最大となった桁数を求める.
                dp[n] = max(dp[n], dp[n - num[a]] + 1)
    # print('各本数丁度で作れる最大桁数')
    # print(dp)

    # 回答となる数値を算出
    ans = ''
    for i in range(dp[N]):  # dp[N]桁の数を上位の桁から決定していく
        for a in A:
            # num[a]本使って数を作ったとき,
            # N - num[a] 本で作れる桁数よりも N 本で作れる桁数のほうが1多い場合,
            # numを作っても最終的に作れる数の桁数は変わらない.
            # そのため dp[N] - 1 == dp[N - num[a]] を満たすような最大のAを作り,
            # 作成する数の上位桁に使用すればよい.
            # 同じ本数のマッチを使用する場合はより大きい数を採用する.
            # そのためAはあらかじめ降順にソートしておく.
            # 最初の条件で配列外アクセスを防ぐ
            if N - num[a] > -1 and dp[N] - 1 == dp[N - num[a]]:
                ans += str(a)
                N -= num[a]
                break
        # print('現在の残本数', N, '採用された数', a)

    print(ans)


if __name__ == '__main__':
    solve()

Submission status: Accepted

Solution code:
costs = [2,5,5,4,5,6,3,7,6]

N, M = map(int, input().split())
A = list(map(int, input().split()))
neginf = -1 * 1e20
D = [neginf]*(N+1)

def dp(n_match):
    D[0] = 0
    for n in range(1,n_match+1):
        arr = [D[n-costs[a-1]] if n-costs[a-1]>=0 else neginf for a in A]
        D[n] = max(arr)+1

def main():
    dp(N)
    n = N
    ans = ''
    while n>1:
        arr = [ a for a in A if  n-costs[a-1]>=0 and D[n-costs[a-1]]==D[n]-1 ]
        if len(arr)>0:
            a = max(arr)
            ans += str(a)
            n -= costs[a-1]
        else:
            break
    print(ans)

main()

Submission status: Accepted

Solution code:
N, M= map(int, input().split())
a_list = sorted(map(int, input().split()), reverse = True)

# インデックスを分かりやすくするために先頭に0を追加
match_num = [0, 2, 5, 5, 4, 5, 6, 3, 7, 6]

inf = 10 ** 5
dp = [-inf] * (N + 1)
dp[0] = 0

# 桁数を調べる
for i in range(1, N+1):
    dp[i] = max([dp[i - match_num[a]] + 1 for a in a_list if i - match_num[a] >= 0] + [-inf])

# 各桁に使う数字を調べる
ans = [""] * dp[N]
rest_match = N
for i in range(dp[N]):
    for a in a_list:
        index = rest_match - match_num[a]
        if index >= 0 and dp[index] == dp[N] - i - 1:
            rest_match -= match_num[a]
            ans[i] = str(a)
            break
print("".join(ans))

Submission status: Accepted

Solution code:
n, m = map(int, input().split())
a = list(map(int, input().split()))
inf = float("inf")
dp = [-inf] * (n+1)
dp[0] = 0
for i in range(1, n+1):
    for j in a:
        cost_j = int("0255456376"[j])
        if i- cost_j >= 0:
            dp[i] = max(dp[i], j+dp[i-cost_j]*10)

ans = dp[n]
if ans == -inf:
    ans = 0
print(ans)

Submission status: Accepted

Solution code:
n, m = map(int, input().split())
a = list(map(int, input().split()))
inf = float("inf")
dp = [-inf] * (n+1)
dp[0] = 0
for i in range(1, n+1):
    for j in a:
        cost_j = int("0255456376"[j])
        if i- cost_j >= 0:
            dp[i] = max(dp[i], j+dp[i-cost_j]*10)
print(dp[n])

Submission status: Accepted

Solution code:
# dpに最大桁数を持たせる
N,M = map(int, input().split())
A = list(map(int, input().split()))
A.sort(reverse=True)
f = [-1, 2,5,5,4,5,6,3,7,6] # 1-indexed

# dp[i]: マッチi本数で作れる最大の桁数(int)
dp = [-float('inf')]*(N+1)
dp[0] = 0
for i in range(N+1):
    nxt = dp[i]
    for aj in A:
        if i-f[aj]<0: continue
        nxt = max(nxt, 
                  dp[i-f[aj]] + 1)
    dp[i] = nxt
    #print(dp)
#print(dp[N])
keta = dp[N]
ans = ""
matchs = N
# 上位の桁から貪欲に
while keta>0:
    for aj in A:
        if matchs-f[aj] < 0: continue
        if dp[matchs-f[aj]] == keta-1:
            ans += str(aj)
            matchs -= f[aj]
            keta -= 1
            break
print(ans)

Submission status: Accepted

Solution code:
# コンテスト中の考えは悪くなかったがN本に固執して貪欲的に考えていた。
# 敗因は動的計画法が思い浮かばず書けなかったこと。
# 提出4298627を参考にした


N, M = map(int, input().split())
A = list(map(int, input().split()))

A.sort(reverse=True)  # 大きい方から探索したいため

# 各数字を作るのに必要なマッチの本数
num = [0, 2, 5, 5, 4, 5, 6, 3, 7, 6]

# dpをするための配列を用意
# pd[i]としたときに、i本のマッチで実現できる最大桁数を格納するものとする
# shapeは(N+1,) ∵ i=0~N本のときも考える
dp = [-1 * float("inf")] * (N + 1)

# 各数字を一つずつ使う場合は1桁だとわかりきっているので、初期化ができる
dp[0] = 0
for a in A:
    if num[a] <= N:  # ここは念のための処理、指定されたNがマッチで使う数字より少ないかもしれない。
        dp[num[a]] = 1

# dpのmain
for i in range(1, N + 1):  # dpに格納されているすべての要素をなめていく。
    for a in A:  # i本使うときの最大桁数を決定するためにはaを全探索して下式を最大となるものが取得できればよい
        if i - num[a] >= 0:  # 念の為の条件
            # この式については解説を参照のこと
            dp[i] = max(dp[i], dp[i - num[a]] + 1)

# 探索が終わったので答えを出す。
# 大きい桁にはなるべく大きな数字を割り振る
ans = ""
for i in range(dp[N]):  # dpによって得た桁数について上位桁から決定していく
    for a in A:  # すでに大きい順にソートしたので決定次第break
        # 1つ目の条件は探索中に配列外アクセスをするのを防ぐため。2つ目の条件についても解説を参照のこと
        if N - num[a] > -1 and dp[N - num[a]] == dp[N] - 1:
            ans += str(a)
            N -= num[a]  # マッチの本数から引くのを忘れずにね
            break

print(ans)

Submission status: Accepted

Solution code:
n, m = map(int, input().split())
a = list(map(int, input().split()))
c = [0, 2, 5, 5, 4, 5, 6, 3, 7, 6]  # マッチ棒の本数との変換
f = [0] + [-1] * 10000  # DP

# マッチ棒の本数分だけ回す
for i in range(n):
    # 入力の1番目(k)は不必要
    i += 1
    for x in a:
        # 数字が大きいほうが良いから全探索
        # ソートしても出来るけれど作るの面倒

        o = c[x]  # マッチ棒の本数に変換

        if i - o >= 0:  # マッチ棒の上限を超えないように判定
            # マッチ棒の本数分だけ減らして桁を繰り上げて足す
            f[i] = max(f[i], f[i - o] * 10 + x)

print(f[n])

Submission status: Accepted

Solution code:
# 解説放送の１つめ
N,M = map(int, input().split())
A = list(map(int, input().split()))
f = [-1, 2,5,5,4,5,6,3,7,6] # 1-indexed

# dp[i]: マッチi本数で作れる最大の数(str)
dp = [None]*(N+1)
dp[0] = ""

# strの数の大きいほう
def max_str(s1:str, s2:str)->str:
    """return bigger one"""
    l1, l2 = len(s1), len(s2)
    if l1 != l2:
        return s1 if l1>l2 else s2
    if l1 == l2: 
        return s1 if s1>s2 else s2
    
for i in range(2, N+1):
    nxt = ""
    for aj in A:
        # 配列外参照と，i本ちょうどで作れないものはだめ
        if i-f[aj]<0 or dp[i-f[aj]]==None: continue
        nxt = max_str(nxt, 
                      dp[i-f[aj]]+str(aj))
    if nxt!="":
        dp[i] = nxt
    #print(dp)
print(dp[N])

Submission status: Accepted

Solution code:
# coding: utf-8
import sys

# import bisect
# import math
# import itertools
# import numpy as np


"""Template"""


class IP:
    """
    入力を取得するクラス
    """

    def __init__(self):
        self.input = sys.stdin.readline

    def I(self):
        """
        1文字の取得に使います
        :return: int
        """
        return int(self.input())

    def S(self):
        """
        1文字の取得(str
        :return: str
        """
        return self.input()

    def IL(self):
        """
        1行を空白で区切りリストにします(int
        :return: リスト
        """
        return list(map(int, self.input().split()))

    def SL(self):
        """
        1行の文字列を空白区切りでリストにします
        :return: リスト
        """
        return list(map(str, self.input().split()))

    def ILS(self, n):
        """
        1列丸々取得します(int
        :param n: 行数
        :return: リスト
        """
        return [int(self.input()) for _ in range(n)]

    def SLS(self, n):
        """
        1列丸々取得します（str
        :param n: 行数
        :return: リスト
        """
        return [self.input() for _ in range(n)]

    def SILS(self, n):
        """
        Some Int LineS
        横に複数、縦にも複数
        :param n: 行数
        :return: list
        """
        return [self.IL() for _ in range(n)]

    def SSLS(self, n):
        """
        Some String LineS
        :param n: 行数
        :return: list
        """
        return [self.SL() for _ in range(n)]


class Idea:
    def __init__(self):
        pass

    def HF(self, p):
        """
        Half enumeration
        半分全列挙です
        pの要素の和の組み合わせを作ります。
        ソート、重複削除行います
        :param p: list : 元となるリスト
        :return: list : 組み合わせられた和のリスト
        """
        return sorted(set(p[i] + p[j] for i in range(len(p)) for j in range(i, len(p))))

    def Bfs2(self, a):
        """
        bit_full_search2
        bit全探索の改良版
        全探索させたら2進数のリストと10進数のリストを返す
        :return: list２つ : １個目 2進数(16桁)  2個目 10進数
        """
        # 参考
        # https://blog.rossywhite.com/2018/08/06/bit-search/
        # https://atcoder.jp/contests/abc105/submissions/4088632
        value = []
        for i in range(1 << len(a)):
            output = []

            for j in range(len(a)):
                if self.bit_o(i, j):
                    """右からj+1番目のiが1かどうか判定"""
                    # output.append(a[j])
                    output.append(a[j])
            value.append([format(i, 'b').zfill(16), sum(output)])

        value.sort(key=lambda x: x[1])
        bin = [value[k][0] for k in range(len(value))]
        val = [value[k][1] for k in range(len(value))]
        return bin, val

    def S(self, s, r=0, m=-1):
        """
        ソート関係行います。色々な設定あります。
        :param s: 元となるリスト
        :param r: reversするかどうか 0=False 1=True
        :param m: （2次元配列）何番目のインデックスのソートなのか
        :return: None
        """
        r = bool(r)
        if m == -1:
            s.sort(reverse=r)
        else:
            s.sort(reverse=r, key=lambda x: x[m])

    def bit_n(self, a, b):
        """
        bit探索で使います。0以上のときにTrue出します
        自然数だからn
        :param a: int
        :param b: int
        :return: bool
        """
        return bool((a >> b & 1) > 0)

    def bit_o(self, a, b):
        """
        bit探索で使います。1のときにTrue出すよ
        oneで1
        :param a: int
        :param b: int
        :return: bool
        """
        return bool(((a >> b) & 1) == 1)

    def ceil(self, x, y):
        """
        Round up
        小数点切り上げ割り算
        :param x: int
        :param y: int
        :return: int
        """
        return -(-x // y)

    def ave(self, a):
        """
        平均を求めます
        :param a: list
        :return: int
        """
        return sum(a) / len(a)

    def gcd(self, x, y):
        if y == 0:
            return x
        else:
            return self.gcd(y, x % y)


"""ここからメインコード"""


def main():
    # 1文字に省略
    r, e = range, enumerate
    ip = IP()
    id = Idea()

    """この下から書いてね"""
    n, m = ip.IL()
    a = ip.IL()
    c = [0, 2, 5, 5, 4, 5, 6, 3, 7, 6]  # マッチ棒の本数との変換
    f = [0] + [-1] * 10000  # DP

    # マッチ棒の本数分だけ回す
    for i in r(n):
        # 入力の1番目(k)は不必要
        i += 1
        for x in a:
            # 数字が大きいほうが良いから全探索
            
            o = c[x]  # マッチ棒の本数に変換   
            
            if i - o >= 0:  # マッチ棒の上限を超えないように判定
                # マッチ棒の本数分だけ減らして桁を繰り上げて足す
                f[i] = max(f[i], f[i - o] * 10 + x)

    print(f[n])


main()

Submission status: Accepted

Solution code:
N,M = map(int, input().split())
A = list(map(int, input().split()))
dp = [None]*(N+1)
dp[0] = ""
f = [-1, 2,5,5,4,5,6,3,7,6] # 1-indexed

def max_str(s1:str, s2:str)->str:
    """return bigger one"""
    l1, l2 = len(s1), len(s2)
    if l1 != l2:
        return s1 if l1>l2 else s2
    if l1 == l2: 
        return s1 if s1>s2 else s2
    
for i in range(2, N+1):
    nxt = ""
    for aj in A:
        if i-f[aj]<0 or dp[i-f[aj]]==None: continue
        nxt = max_str(nxt, 
                      dp[i-f[aj]]+str(aj))
    if nxt!="":
        dp[i] = nxt
    #print(dp)
print(dp[N])

Submission status: Accepted

Solution code:
n, m = map(int, input().split())
a = list(map(int, input().split()))

inf = float("inf")
dp = [-inf for i in range(n+1)]
dp[0] = 0

cost = {1:2, 2:5, 3:5, 4:4, 5:5, 6:6, 7:3, 8:7, 9:6}

for i in a:
    for j in range(1, n+1):
        if j - cost[i] >= 0:
            dp[j] = max(dp[j], dp[j-cost[i]]+1)

a.sort(reverse=True)
ans = ""
while n > 0:
    for i in a:
        state = True
        if n-cost[i] >= 0 and dp[n-cost[i]] == dp[n]-1:
            ans += str(i)
            n -= cost[i]
            state = False
            break
    if state:
        break

if ans == "":
    print(0)
else:
    print(ans)

Submission status: Accepted

Solution code:
from bisect import bisect_left, bisect_right
from collections import Counter, defaultdict, deque, OrderedDict
from copy import deepcopy
from functools import lru_cache, reduce
from math import ceil, floor
from sys import setrecursionlimit

import heapq
import itertools
import operator


inf = float('inf')


def get_int():
    return int(input())


def get_str():
    return input().strip()


def get_int_list():
    return [int(i) for i in input().split()]


def get_char_list():
    return list(input().strip())


COST = {
    1: 2,
    2: 5,
    3: 5,
    4: 4,
    5: 5,
    6: 6,
    7: 3,
    8: 7,
    9: 6
}


# inputs
N, M = 0, 0
A = [0]


def hoge():
    d = dict()
    def labeler(label, iter):
        enumerate()


def set_inputs():
    global N, M, A
    N, M = get_int_list()
    A = get_int_list()


@lru_cache(maxsize=None)
def dp(i):
    if i < 0:
        return -inf
    elif i == 0:
        return 0
    return max(dp(i - COST[a]) + 1 for a in A)


def main():
    setrecursionlimit(100000)
    set_inputs()

    candidates = sorted(A, reverse=True)
    ret = []
    n = N
    for i in range(dp(N)):
        for a in candidates:
            cond = True
            if i == dp(N) - 1:
                cond = COST[a] == n
            if dp(n - COST[a]) == dp(n) - 1 and cond:
                ret.append(a)
                n -= COST[a]
                break
    print(''.join(str(r) for r in ret))


if __name__ == '__main__':
    main()