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

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Time Limit Exceeded)


import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Scanner;
import java.util.stream.Collectors;

public class Main {
    private static final Map<Integer, Integer> MAPPING = buildMapping();

    private static Map<Integer, Integer> buildMapping() {
        Map<Integer, Integer> map = new HashMap<>();
        map.put(1, 2);
        map.put(2, 5);
        map.put(3, 5);
        map.put(4, 4);
        map.put(5, 5);
        map.put(6, 6);
        map.put(7, 3);
        map.put(8, 7);
        map.put(9, 6);
        return map;
    }

    public static void main(String[] args) {
        TestCase testCase = readFromInput();

        String number = findLargestNumber(testCase);

        output(number);
    }

    private static TestCase readFromInput() {
        Scanner sc = new Scanner(System.in);
        final int N = sc.nextInt();
        final int M = sc.nextInt();

        List<Integer> A = new ArrayList<>();
        for (int i = 0; i < M; ++i) {
            int AN = sc.nextInt();
            A.add(AN);
        }

        sc.close();

        return new TestCase(N, A);
    }

    private static final Optional<String> NO_ANSWER = Optional.empty();

    public static String findLargestNumber(TestCase testCase) {
        final int N = testCase.N;
        final List<Integer> A = testCase.A;
        List<Optional<String>> answers = new ArrayList<>();
        answers.add(0, NO_ANSWER);

        for (int i = 1; i <= N; ++i) {
            final int iFinal = i; // to circumvent the stream limitation in Java
            answers.add(
                    i,
                    A.stream()
                            .map(digit -> {
                                final Integer numMatchesNeeded = MAPPING.get(digit);
                                if (isOneMoreDigitPossible(answers, iFinal, numMatchesNeeded)) {
                                    return Optional.of(oneMoreDigit(answerWithoutDigit(answers, iFinal, numMatchesNeeded).get(), digit));
                                } else if (iFinal == numMatchesNeeded) {
                                    return Optional.of(digit.toString());
                                } else {
                                    return NO_ANSWER;
                                }
                            })
                            .filter(Optional::isPresent)
                            .map(Optional::get)
                            .max(Comparator.comparing(BigInteger::new))
            );
        }

        return answers.get(N).orElseThrow(() -> new IllegalStateException("No solution for " + N));
    }

    private static boolean isOneMoreDigitPossible(List<Optional<String>> answers, int iFinal, Integer numMatchesNeeded) {
        final boolean hasEnoughMatches = iFinal > numMatchesNeeded;
        if (hasEnoughMatches) {
            return answerWithoutDigit(answers, iFinal, numMatchesNeeded).isPresent();
        } else {
            return false;
        }
    }

    private static Optional<String> answerWithoutDigit(List<Optional<String>> answers, int iFinal, Integer numMatchesNeeded) {
        return answers.get(iFinal - numMatchesNeeded);
    }

    private static String oneMoreDigit(String answerWithoutDigit, Integer digit) {
        return (answerWithoutDigit + digit.toString()).chars()
                .mapToObj(c -> (char) c)
                .sorted(Collections.reverseOrder())
                .map(Object::toString)
                .collect(Collectors.joining());
    }

    private static void output(String str) {
        System.out.println(str);
    }

    public static class TestCase {
        final int N;
        final List<Integer> A;

        public TestCase(int N, List<Integer> A) {
            this.N = N;
            this.A = A;
        }
    }

}