Problem:
Score : 300 points

Problem

Takahashi, who is a novice in competitive programming, wants to learn M algorithms.
Initially, his understanding level of each of the M algorithms is 0.

Takahashi is visiting a bookstore, where he finds N books on algorithms.
The i-th book (1\leq i\leq N) is sold for C_i yen (the currency of Japan). If he buys and reads it, his understanding level of the j-th algorithm will increase by A_{i,j} for each j (1\leq j\leq M).
There is no other way to increase the understanding levels of the algorithms.

Takahashi's objective is to make his understanding levels of all the M algorithms X or higher. Determine whether this objective is achievable. If it is achievable, find the minimum amount of money needed to achieve it.

Constraints

All values in input are integers.

1\leq N, M\leq 12

1\leq X\leq 10^5

1\leq C_i \leq 10^5

0\leq A_{i, j} \leq 10^5

Input

Input is given from Standard Input in the following format:

N M X
C_1 A_{1,1} A_{1,2} \cdots A_{1,M}
C_2 A_{2,1} A_{2,2} \cdots A_{2,M}
\vdots
C_N A_{N,1} A_{N,2} \cdots A_{N,M}

Output

If the objective is not achievable, print -1; otherwise, print the minimum amount of money needed to achieve it.

Sample Input 1

3 3 10
60 2 2 4
70 8 7 9
50 2 3 9

Sample Output 1

120

Buying the second and third books makes his understanding levels of all the algorithms 10 or higher, at the minimum cost possible.

Sample Input 2

3 3 10
100 3 1 4
100 1 5 9
100 2 6 5

Sample Output 2

-1

Buying all the books is still not enough to make his understanding levels of all the algorithms 10 or higher.

Sample Input 3

8 5 22
100 3 7 5 3 1
164 4 5 2 7 8
334 7 2 7 2 9
234 4 7 2 8 2
541 5 4 3 3 6
235 4 8 6 9 7
394 3 6 1 6 2
872 8 4 3 7 2

Sample Output 3

1067

Solution in C# (.NET Core 3.1.201) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;

namespace x
{
    class Program
    {
        class BookInfo
        {
            public readonly int price;
            public readonly int[] lvUps;

            public BookInfo(int[] nums)
            {
                this.price = nums[0];
                this.lvUps = nums.Skip(1).ToArray();
            }
        }

        static void Main(string[] args)
        {
            (var bookCount, var algoCount, var goal) = IOUtils.Read3Ints();

            var books = Enumerable.Repeat(0, bookCount)
                                .Select(_ => IOUtils.ReadInts())
                                .Select(n => new BookInfo(n))
                                .ToArray();

            var allCandidates = Enumerable.Range(1, bookCount)
                                          .SelectMany(cnt => MathUtils.EnumCombination(books, cnt, false))
                                          .ToList() as List<BookInfo[]>;

            var result = allCandidates.OrderBy(c => c.Sum(b => b.price))
                                      .FirstOrDefault(c => isFilled(c, goal, algoCount));
            System.Console.WriteLine(result == null ? -1 : result.Sum(b => b.price));
        }

        static bool isFilled(IList<BookInfo> books, int goal, int algoCount)
        {
            var summed = new int[algoCount];
            foreach (var book in books)
            {
                for (int i = 0; i < book.lvUps.Length; i++)
                {
                    summed[i] += book.lvUps[i];
                }
            }

            return summed.All(l => l >= goal);
        }
    }


    static class MathUtils
    {
        /// <summary>
        /// 最大公約数
        /// </summary>
        /// <param name="nums"></param>
        /// <returns></returns>
        public static ulong Gcd(params ulong[] nums)
        {
            if (nums.Length == 0) return 0;
            if (nums.Length == 1) return nums.Single();

            var tmp = nums[0];
            var rest = new Queue<ulong>(nums.Skip(1));
            while (rest.Any())
            {
                tmp = gcd(tmp, rest.Dequeue());
            }
            return tmp;
        }
        private static ulong gcd(ulong a, ulong b)
        {
            while (true)
            {
                if (a % b == 0)
                {
                    return b;
                }
                else
                {
                    var x = a % b;
                    a = b;
                    b = x;
                }
            }
        }

        /// <summary>
        /// 最小公倍数
        /// </summary>
        /// <param name="nums"></param>
        /// <returns></returns>
        public static ulong Lcm(params ulong[] nums)
        {
            if (nums.Length == 0) return 0;
            if (nums.Length == 1) return nums.Single();

            var tmp = nums[0];
            var rest = new Queue<ulong>(nums.Skip(1));
            while (rest.Any())
            {
                tmp = lcm(tmp, rest.Dequeue());
            }
            return tmp;
        }

        private static ulong lcm(ulong a, ulong b)
        {
            return a / gcd(a, b) * b;
        }

        /// <summary>
        /// 素因数分解
        /// </summary>
        /// <param name="n"></param>
        /// <returns></returns>
        public static IEnumerable<long> PrimeFactors(long n)
        {
            int i = 2;
            long tmp = n;

            while (i * i <= n)
            {
                if (tmp % i == 0)
                {
                    tmp /= i;
                    yield return i;
                }
                else
                {
                    i++;
                }
            }
            if (tmp != 1) yield return tmp;
        }

        /// <summary>
        /// 順列の数を返す
        /// </summary>
        /// <param name="n"></param>
        /// <param name="k"></param>
        /// <returns></returns>
        public static long P(long n, long k)
        {
            if (n < k) return 0;
            if (n == k) return 1;

            long x = 1;
            for (long i = 0; i < k; i++)
            {
                x = x * (n - i);
            }
            return x;
        }

        /// <summary>
        /// 組み合わせの数を返す
        /// </summary>
        /// <param name="n"></param>
        /// <param name="k"></param>
        /// <returns></returns>
        public static long C(long n, long k)
        {
            if (n < k) return 0;
            if (n == k) return 1;

            long x = 1;
            for (long i = 0; i < k; i++)
            {
                x = x * (n - i) / (i + 1);
            }
            return x;
        }

        /// <summary>
        /// 順列を列挙（幅優先）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="src"></param>
        /// <param name="k"></param>
        /// <returns></returns>
        public static IEnumerable<T[]> EnumPermutations<T>(IReadOnlyList<T> src, int k)
        {
            if (src.Count < k || k <= 0) throw new ArgumentOutOfRangeException(nameof(k));

            var queue = new Queue<List<int>>(Enumerable.Range(0, src.Count).Select(i => new List<int>() { i }));
            while (queue.Any())
            {
                var indexes = queue.Dequeue();

                if (indexes.Count == k)
                {
                    yield return indexes.Select(i => src[i]).ToArray();
                    continue;
                }

                for (int index = 0; index < src.Count; index++)
                {
                    if (indexes.Contains(index))
                    {
                        continue;
                    }

                    var newIndexes = new List<int>(indexes);
                    newIndexes.Add(index);
                    queue.Enqueue(newIndexes);
                }
            }
        }

        /// <summary>
        /// 組み合わせを列挙
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="src"></param>
        /// <param name="k"></param>
        /// <param name="allowsRepetition"></param>
        /// <returns></returns>
        public static IEnumerable<T[]> EnumCombination<T>(IReadOnlyList<T> src, int k, bool allowsRepetition)
        {
            if (k == 1)
            {
                foreach (var item in src)
                {
                    yield return new T[] { item };
                }
                yield break;
            }
            foreach (var item in src)
            {
                var leftside = new T[] { item };

                var unused = src.SkipWhile(e => !e.Equals(item)).Skip(allowsRepetition ? 0 : 1).ToList();

                foreach (var rightside in EnumCombination(unused, k - 1, allowsRepetition))
                {
                    yield return leftside.Concat(rightside).ToArray();
                }
            }
        }
    }
    
    static class IOUtils
    {
        public static (int a, int b) Read2Ints()
        {
            var vals = ReadInts();
            return (vals[0], vals[1]);
        }
        public static (int a, int b, int c) Read3Ints()
        {
            var vals = ReadInts();
            return (vals[0], vals[1], vals[2]);
        }
        public static IEnumerable<int[]> ReadIntLines(int count)
        {
            for (int i = 0; i < count; i++)
            {
                yield return ReadInts();
            }
        }
        public static IEnumerable<long[]> ReadLongLines(int count)
        {
            for (int i = 0; i < count; i++)
            {
                yield return ReadLongs();
            }
        }
        public static int ReadInt()
        {
            return int.Parse(Console.ReadLine());
        }
        public static long ReadLong()
        {
            return long.Parse(Console.ReadLine());
        }
        public static ulong ReadUlong()
        {
            return ulong.Parse(Console.ReadLine());
        }
        public static int[] ReadInts()
        {
            return Console.ReadLine().Split(' ').Select(v => int.Parse(v)).ToArray();
        }
        public static long[] ReadLongs()
        {
            return Console.ReadLine().Split(' ').Select(v => long.Parse(v)).ToArray();
        }

        public static void WriteNums(params int[] nums)
        {
            Console.WriteLine(string.Join(" ", nums));
        }
    }
}