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 Go (1.14.1) (judge verdict: Runtime Error)

package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"strconv"
	"strings"
)

type rowDataType struct {
	amount int
	learningPoints map[int]int
}

type stdInStruct struct {
	// read data
	numBook int // 1行目のn (行数)
	numAlgo int // 1行目のm (列数)
	numArrival int // 1行目のx
	rowData map[int]*rowDataType // 読み取ったデータそのまま

	// workspace
	totalAmount int // 購入順が確定した行の価格を足し合わせる
	tmpRowData map[int]*rowDataType // 購入順が確定したものからデータを除去する
	understandTarget map[int]int // 各アルゴリズムで理解が必要な残りポイント
}

func main() {
	s := initStdInStruct()

	for cnt := 0; cnt < s.numBook; cnt++ {
		idx := s.calcTopEfficiencyIndex()
		s.applyEfficiencyIndex(idx)
		if s.checkEnd() {
			fmt.Print(s.totalAmount)
			return
		}
	}

	if !s.checkEnd() {
		fmt.Print(-1)
		return
	}
	fmt.Print(s.totalAmount)
}

var sc = bufio.NewScanner(os.Stdin)
func readLine() string {
	sc.Scan()
	return sc.Text()
}

func mapInt(input []string) []int {
	r := make([]int, len(input))
	for i, e := range input {
		r[i], _ = strconv.Atoi(e)
	}
	return r
}

func initStdInStruct() stdInStruct {
	calcStruct := stdInStruct{}

	// initialize
	tmp := strings.Split(readLine(), " ")
	nmx := mapInt(tmp)
	calcStruct.numBook, calcStruct.numAlgo, calcStruct.numArrival = nmx[0], nmx[1], nmx[2]
	calcStruct.rowData = make(map[int]*rowDataType)
	for i := 0; i < calcStruct.numBook; i++ {
		calcStruct.rowData[i] = &rowDataType{}
		calcStruct.rowData[i].learningPoints = make(map[int]int)
	}

	// readline
	for cnt := 0; cnt < calcStruct.numBook; cnt++ {
		tmp = strings.Split(readLine(), " ")
		line := mapInt(tmp)
		calcStruct.rowData[cnt].amount = line[0]
		skillUp := line[1:]
		total := 0
		for i, e := range skillUp {
			calcStruct.rowData[cnt].learningPoints[i] = e
			total += e
		}
	}

	calcStruct.clear()
	return calcStruct
}

func (s *stdInStruct) clear() {
	s.totalAmount = 0

	s.tmpRowData = make(map[int]*rowDataType)
	for key1, val1 := range s.rowData {
		s.tmpRowData[key1] = &rowDataType{}
		s.tmpRowData[key1].amount = val1.amount
		s.tmpRowData[key1].learningPoints = make(map[int]int)
		for key2, val2 := range val1.learningPoints {
			s.tmpRowData[key1].learningPoints[key2] = val2
		}
	}

	s.understandTarget = make(map[int]int)
	for cnt := 0; cnt < s.numAlgo; cnt++ {
		s.understandTarget[cnt] = s.numArrival
	}
}

func (s stdInStruct) calcCurrentTotalAmount() int {
	total := 0
	for _, val1 := range s.tmpRowData {
		total += val1.amount
	}
	return total
}

func (s stdInStruct) calcCurrentAmountRatio() map[int]float64 {
	totalAmount := float64(s.calcCurrentTotalAmount())
	rtn := make(map[int]float64)
	for key, val := range s.tmpRowData {
		rtn[key] = float64(val.amount) / totalAmount
	}
	return rtn
}

func (s stdInStruct) calcCurrentLearningRatio() map[int]float64 {
	rtn := make(map[int]float64)
	for key1, val1 := range s.tmpRowData {
		ratio := 0.0
		cnt := 0
		for key2, val2 := range val1.learningPoints {
			ratio += math.Min(float64(val2) / float64(s.understandTarget[key2]), 1.0)
			cnt++
		}
		rtn[key1] = ratio / float64(cnt)
	}
	return rtn
}

func (s stdInStruct) calcTopEfficiencyIndex() int {
	amountRatio := s.calcCurrentAmountRatio()
	learningRatio := s.calcCurrentLearningRatio()
	currentEfficiencyRatio := 10.0
	rtn := -1
	for idx := range s.tmpRowData {
		if efficiency := amountRatio[idx] - learningRatio[idx]; efficiency < currentEfficiencyRatio {
			currentEfficiencyRatio = efficiency
			rtn = idx
		}
	}
	return rtn
}

func (s *stdInStruct) applyEfficiencyIndex(idx int) {
	s.totalAmount += s.tmpRowData[idx].amount
	var deleteCol []int
	for col := range s.understandTarget {
		s.understandTarget[col] -= s.tmpRowData[idx].learningPoints[col]
		if s.understandTarget[col] <= 0 {
			deleteCol = append(deleteCol, col)
		}
	}
	for _, col := range deleteCol {
		delete(s.understandTarget, col)
	}
	delete(s.tmpRowData, idx)
}

func (s stdInStruct) checkEnd() bool {
	return len(s.understandTarget) == 0
}