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)

//
// ABC167C
// URL : https://atcoder.jp/contests/abc167/tasks/abc167_c
// 
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;

namespace AtCoder
{
    class ABC167C
    {
        public static readonly long MOD_CONST = 1000000007;//(long)Math.Pow(10, 9) + 7;

        static void Main(string[] args)
        {
            //出力高速化
            var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
            Console.SetOut(sw);
            Solve();
            Console.Out.Flush();
        }
        public static int N, M, X;

        public static void Solve()
        {
            {
                long[] inputLongArray = Console.ReadLine().Split(' ').Select(_inputStr => long.Parse(_inputStr)).ToArray();
                N = (int)inputLongArray[0];
                M = (int)inputLongArray[1];
                X = (int)inputLongArray[2];//目標理解度
            }
            var CList = new int[N];
            var AList = new int[N, M];
            for(int i = 0; i < N; ++i)
            {
                long[] inputLongArray = Console.ReadLine().Split(' ').Select(_inputStr => long.Parse(_inputStr)).ToArray();
                CList[i] = (int)inputLongArray[0];
                for(int m = 0; m < M; ++m)
                {
                    AList[i, m] = (int)inputLongArray[m + 1];
                }
            }

            //bit全探索する
            {
                int ans = int.MaxValue;
                for (int bit = 0; bit < (1 << N); ++bit)
                {
                    var MList = new int[M];//理解度
                    int cost = 0;
                    for (int i = 0; i < N; ++i) {
                        if ( (bit & (1 << i)) > 0)//bitが立っていたら購入
                        {
                            bool complete = true;
                            //理解度up
                            for (int mi = 0; mi < M; ++mi)
                            {
                                MList[mi] += AList[i, mi];
                                if(MList[mi] < X) { complete = false; }
                            }
                            //コストup
                            cost += CList[i];
                            //全部完全に理解していたら
                            if(complete == true)
                            {
                                ans = Math.Min(ans, cost);
                            }
                        }
                    }
                }
                //どんな組み合わせで参考書を買っても無理
                if (ans == int.MaxValue)
                {
                    Console.WriteLine("-1");
                }
                else
                {
                    Console.WriteLine(ans);
                }
                return;
            }
        }


        //---------------------------------------------------------------------------------

        /// <summary>
        /// 指定された底log_baseでの, 対数を計算
        /// </summary>
        /// <param name="x"></param>
        /// <param name="log_base">指定の底</param>
        /// <returns></returns>
        public static double LogBase(double x, double log_base)
        {
            //log_b(N) = log_a(N) / log_a(B)より
            return Math.Log(x) / Math.Log(log_base);
        }

        /// <summary>
        /// 初項a, 公差d, 項数nの数列の和
        /// </summary>
        /// <param name="n">求めたいところ</param>
        /// <returns>初項からxまで足した値</returns>
        static long SumSeries(long a, long d, long n)
        {
            return (2 * a + (n-1) * d) * n / 2;
        }
        /// <summary>
        /// 累積和の配列を計算する
        /// Sum[ a[0], a[i] )がs[i+1]に入っている
        /// s[0]  : 0                //一切和を取らない場合
        /// s[1]  : ls[0]            //a[0]   + s[0] = a[0]
        /// s[2]  : ls[1] + s[1]     //a[1]   + a[0]
        /// ...
        /// s[N]  : ls[N-1] + s[N-1] //a[N-1] + ... + a[0]
        /// s[N+1]: ls[N] + s[N]     //a[N]   + ... + a[0]
        /// 
        /// 例: [1, 7)の和(a[1] + ... + a[6])
        /// s[1] = a[0] //[0, 1)
        /// s[7] = a[0] + a[1] + ... + a[6] //[0, 7)
        /// よってs[7] - s[1]);
        /// </summary>
        /// <param name="ls">計算したい配列</param>
        /// <returns>累積和配列</returns>
        static List<long> AggregateSumList(List<long> a)
        {
            var s = new List<long>(a.Count+1);
            if(a.Count == 0)
            {
                return s;
            }
            s.Add(0);//s[0] = 0
            for(int i = 0; i < a.Count; ++i)
            {
                s.Add(a[i] + s[i]);
            }
            return s;
        }


        /// <summary>
        /// 与えられた数が素数かどうかを計算する
        /// </summary>
        /// <param name="num">対象数</param>
        /// <returns>true:素数, false:素数ではない(合成数)</returns>
        public static bool isPrime(int num)
        {
            if (num < 2) return false;
            else if (num == 2) return true;
            else if (num % 2 == 0) return false;

            double sqrtNum = Math.Sqrt(num);
            for (int i = 3; i <= sqrtNum; i += 2)
            {
                if (num % i == 0)
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 順列mPnを計算する
        /// </summary>
        /// <param name="m"></param>
        /// <param name="n"></param>
        /// <returns></returns>
        public static long Permutation(long m, long n)
        {
            long ret = 1;
            for(var i = 0; i < n; ++i)
            {
                ret *= m - i;
            }
            return ret;
        }
        /// <summary>
        /// 組み合わせmCnを計算する
        /// </summary>
        /// <param name="m"></param>
        /// <param name="n"></param>
        /// <returns></returns>
        public static long Combination(long m, long n)
        {
            if (m == n || n == 0)
            {
                return 1;
            }
            long ans = 1;
            for (var i = 1; i <= n; ++i)
            {
                ans = ans * (m - i + 1) / i;
            }
            return ans;
        }

        static long Gcd(long m, long n)
        {
            if (n == 0) return m;
            return Gcd(n, m % n);
        }

        static long Lcm(long m, long n)
        {
            var gcd = Gcd(m, n);
            //return (m * n) / gcd;
            return m / gcd * n;//桁あふれ対策
        }
    }
}