← Home
package main

import (
	"bufio"
	"fmt"
	"os"
)

var (
	n, k     int
	pref     []int
	dpPrev   []int64
	dpCurr   []int64
	costL    int   = 1
	costR    int   = 0
	currCost int64 = 0
)

const INF int64 = 1e18



func getCost(l, r int) int64 {
	if l > r {
		return 0
	}

	
	for costR < r {
		costR++
		if costL <= costR-1 {
			rowOff := costR * (n + 1)
			currCost += int64(pref[rowOff+costR-1] - pref[rowOff+costL-1])
		}
	}
	
	for costL > l {
		costL--
		if costL+1 <= costR {
			rowOff := costL * (n + 1)
			currCost += int64(pref[rowOff+costR] - pref[rowOff+costL])
		}
	}
	
	for costR > r {
		if costL <= costR-1 {
			rowOff := costR * (n + 1)
			currCost -= int64(pref[rowOff+costR-1] - pref[rowOff+costL-1])
		}
		costR--
	}
	
	for costL < l {
		if costL+1 <= costR {
			rowOff := costL * (n + 1)
			currCost -= int64(pref[rowOff+costR] - pref[rowOff+costL])
		}
		costL++
	}
	return currCost
}


func solve(L, R, optL, optR int) {
	if L > R {
		return
	}

	mid := (L + R) >> 1
	bestP := -1
	minVal := INF

	limit := optR
	if mid-1 < limit {
		limit = mid - 1
	}

	
	for p := optL; p <= limit; p++ {
		if dpPrev[p] == INF {
			continue
		}
		val := dpPrev[p] + getCost(p+1, mid)
		if val < minVal {
			minVal = val
			bestP = p
		}
	}

	dpCurr[mid] = minVal
	
	
	pRec := bestP
	if pRec == -1 {
		pRec = optL
	}

	solve(L, mid-1, optL, pRec)
	solve(mid+1, R, pRec, optR)
}

func main() {
	
	scanner := bufio.NewScanner(os.Stdin)
	buf := make([]byte, 256*1024)
	scanner.Buffer(buf, 64*1024*1024) 
	scanner.Split(bufio.ScanWords)

	readInt := func() int {
		scanner.Scan()
		b := scanner.Bytes()
		x := 0
		for _, c := range b {
			x = x*10 + int(c-'0')
		}
		return x
	}

	if !scanner.Scan() {
		return
	}
	
	
	b := scanner.Bytes()
	for _, c := range b {
		n = n*10 + int(c-'0')
	}
	k = readInt()

	
	pref = make([]int, (n+1)*(n+1))
	for i := 1; i <= n; i++ {
		rowOff := i * (n + 1)
		sum := 0
		for j := 1; j <= n; j++ {
			val := readInt()
			sum += val
			pref[rowOff+j] = sum
		}
	}

	dpPrev = make([]int64, n+1)
	dpCurr = make([]int64, n+1)

	
	for i := 1; i <= n; i++ {
		dpPrev[i] = INF
	}
	dpPrev[0] = 0

	
	for j := 1; j <= k; j++ {
		solve(j, n, j-1, n-1)
		copy(dpPrev, dpCurr)
	}

	fmt.Println(dpPrev[n])
}