Buggy python submission (verdict: Time Limit Exceeded):
from itertools import accumulate
from operator import add


h, w, k = map(int, input().split())

white_count = [0] * (w+1)
prev = [0] * (w+1)
for _ in range(h):
    line = iter('0'+input())
    cumsum_1d = accumulate(map(int, line))
    cumsum_2d = list(map(add, prev, cumsum_1d))
    prev = cumsum_2d
    white_count += cumsum_2d


def get_white(sy, sx, ny, nx):
    a = sy*(w+1) + sx
    b = sy*(w+1) + nx
    c = ny*(w+1) + sx
    d = ny*(w+1) + nx
    return white_count[d] - white_count[c] - white_count[b] + white_count[a]


ans = []
for pattern in range(2**(h-1)):
    dived = [0] + [y+1 for y in range(h-1) if (pattern>>y) & 1] + [h]
    slash_count = len(dived) - 2

    prev_x = 0
    for div_x in range(1, w + 1):
        white_include = 0
        for idx in range(len(dived)-1):
            prev_y = dived[idx]
            div_y = dived[idx+1]
            white = get_white(prev_y, prev_x, div_y, div_x)
            if white > white_include:
                white_include = white

        if white_include > k:
            slash_count += 1
            if prev_x == div_x - 1:
                break
            prev_x = div_x - 1

    else:
        ans.append(slash_count)

print(min(ans))


Fixed submission:
h, w, k = map(int, input().split())
chocolate = ['0' + input() for _ in range(h)]

white_count = [[0] * (w+1)]
for line in chocolate:
    prev = white_count[-1]
    cumsum = []
    total = 0
    for color, count in zip(line, prev):
        if color == '1':
            total += 1
        cumsum.append(total + count)
    white_count.append(cumsum)

ans = []
for pattern in range(2**(h-1)):
    dived = []
    for y in range(h-1):
        if (pattern >> y) & 1:
            dived.append(y + 1)

    dived.append(h)
    slash_count = len(dived) - 1

    prev_x = 0
    for nx in range(1, w + 1):
        prev_y = 0
        possible = True
        for ny in dived:
            white = white_count[ny][nx] - white_count[prev_y][nx] - (white_count[ny][prev_x] - white_count[prev_y][prev_x])
            prev_y = ny
            if white <= k:
                continue
            else:
                slash_count += 1
                slash = nx - 1
                if prev_x == slash:
                    possible = False
                prev_x = slash
                break

        if not possible:
            break

    else:
        ans.append(slash_count)

print(min(ans))

Buggy python submission (verdict: Time Limit Exceeded):
import numpy as np


h, w, k = map(int, input().split())
white_count = [np.zeros(w+1, dtype=np.int64)]

for _ in range(h):
    line = list(map(int, list('0'+input())))
    count = np.cumsum(line)
    white_count.append(count + white_count[-1])

white_count = np.array(white_count)

ans = []
for pattern in range(2 ** (h-1)):
    dived_y = [0]
    for y in range(h-1):
        if (pattern >> y) & 1:
            dived_y.append(y + 1)
    dived_y.append(h)

    slash_count = len(dived_y) - 2
    pre_y = dived_y[:-1]
    ny = dived_y[1:]

    prev_x = 0
    for nx in range(1, w+1):
        pre_x_arr = white_count[:, prev_x]
        nx_arr = white_count[:, nx]
        whites = nx_arr[ny] - nx_arr[pre_y] - pre_x_arr[ny] + pre_x_arr[pre_y]
        white = whites.max()
        if white <= k:
            continue
        else:
            slash = nx - 1
            if slash == prev_x:
                break
            slash_count += 1
            prev_x = slash

    else:
        ans.append(slash_count)

print(min(ans))

Fixed submission:
h, w, k = map(int, input().split())
chocolate = ['0' + input() for _ in range(h)]

white_count = [[0] * (w+1)]
for line in chocolate:
    prev = white_count[-1]
    cumsum = []
    total = 0
    for color, count in zip(line, prev):
        if color == '1':
            total += 1
        cumsum.append(total + count)
    white_count.append(cumsum)

ans = []
for pattern in range(2**(h-1)):
    dived = []
    for y in range(h-1):
        if (pattern >> y) & 1:
            dived.append(y + 1)

    dived.append(h)
    slash_count = len(dived) - 1

    prev_x = 0
    for nx in range(1, w + 1):
        prev_y = 0
        possible = True
        for ny in dived:
            white = white_count[ny][nx] - white_count[prev_y][nx] - (white_count[ny][prev_x] - white_count[prev_y][prev_x])
            prev_y = ny
            if white <= k:
                continue
            else:
                slash_count += 1
                slash = nx - 1
                if prev_x == slash:
                    possible = False
                prev_x = slash
                break

        if not possible:
            break

    else:
        ans.append(slash_count)

print(min(ans))