Buggy python submission (verdict: Time Limit Exceeded):
h, w, k = map(int, input().split())
S = [[int(s) for s in list(input())] for i in range(h)]
ans = 10**4
for b in range(2**(h-1)):
    cnt = bin(b).count('1')
    B = format(b, 'b').zfill(h-1)+'1'
    T = [[0]*w for i in range(cnt+1)]
    for j in range(w):
        t, c = 0, 0
        for i in range(h):
            t += S[i][j]
            if B[i] == '1':
                T[c][j] += t
                t = 0
                c += 1
    if max([max(T[i]) for i in range(cnt+1)]) > k:
        continue
    A = [T[i][0] for i in range(cnt+1)]
    tmp = cnt
    for j in range(1, w):
        A = [A[i]+T[i][j] for i in range(cnt+1)]
        if any([a > k for a in A]):
            A = [T[i][j] for i in range(cnt+1)]
            tmp += 1
    ans = min(ans, tmp)
print(ans)


Fixed submission:
# 部分リストのリスト
def all_sublist(lst):
    lstlst = []
    for i in range(2**len(lst)):
        sublst = []
        for j in range(len(lst)):
            if (i >> j) & 1 == 1:
                sublst.append(lst[j])
        lstlst.append(sublst)
    return lstlst


# 入力
H, W, K = map(int, input().split())
S = [[int(x) for x in list(input())] for h in range(H)]

# 横方向にカットする位置の列挙
cutlst = all_sublist(list(range(1, H)))

# 横方向の切り方を動かして切る数の合計の最小値を求める
cnt_min = 10**9 + 7
for cut in cutlst:
    # 横方向に切って圧縮したものをSSとする
    SS = []
    cut.append(H)
    start = 0
    for stop in cut:
        T = []
        for w in range(W):
            tmp = 0
            for h in range(start, stop):
                tmp += S[h][w]
            T.append(tmp)
        SS.append(T)
        start = stop
    H0 = len(SS)
    # K以上の成分があったらこのcutはパス
    if any([SS[h][w] > K for h in range(H0) for w in range(W)]):
        continue
    # 縦方向に切る数を数える
    cnt = len(cut) - 1
    left = [0 for h in range(H0)]
    right = [SS[h][0] for h in range(H0)]
    for w in range(1, W):
        left, right = right, [right[h] + SS[h][w] for h in range(H0)]
        leftOK = all([left[h] <= K for h in range(H0)])
        rightNG = any([right[h] > K for h in range(H0)])
        # すべての成分がK以下になるギリギリのところで切る
        if leftOK and rightNG:
            left = [0 for h in range(H0)]
            right = [SS[h][w] for h in range(H0)]
            cnt += 1
    cnt_min = min(cnt_min, cnt)
print(cnt_min)

Buggy python submission (verdict: Time Limit Exceeded):
# 部分リストのリスト
def all_sublist(lst):
    lstlst = []
    for i in range(2**len(lst)):
        sublst = []
        for j in range(len(lst)):
            if (i >> j) & 1 == 1:
                sublst.append(lst[j])
        lstlst.append(sublst)
    return lstlst


# 入力
H, W, K = map(int, input().split())
S = [[int(x) for x in list(input())] for h in range(H)]

# 横方向にカットする位置の列挙
cutlst = all_sublist(list(range(1, H)))

# 横方向の切り方を動かして切る数の合計の最小値を求める
cnt_min = 10**9 + 7
for cut in cutlst:
    # 横方向に切って圧縮したものをSSとする
    SS = []
    cut.append(H)
    start = 0
    for stop in cut:
        T = []
        for w in range(W):
            tmp = 0
            for h in range(start, stop):
                tmp += S[h][w]
            T.append(tmp)
        SS.append(T)
        start = stop
    H0 = len(SS)
    # K以上の成分があったらこのcutはパス
    if any([SS[h][w] > K for h in range(H0) for w in range(W)]):
        continue
    # 縦方向に切る数を数える
    cnt = len(cut) - 1
    left = [0 for h in range(H0)]
    right = [SS[h][0] for h in range(H0)]
    for w in range(1, W):
        left, right = right, [right[h] + SS[h][w] for h in range(H0)]
        leftOK = all([left[h] <= K for h in range(H0)])
        rightNG = any([right[h] > K for h in range(H0)])
        # すべての成分がK以下になるギリギリのところで切る
        if leftOK and rightNG:
            left = [0 for h in range(H0)]
            right = [SS[h][w] for h in range(H0)]
            cnt += 1
    cnt_min = min(cnt_min, cnt)
print(cnt_min)


Fixed submission:
# 部分リストのリスト
def all_sublist(lst):
    lstlst = []
    for i in range(2**len(lst)):
        sublst = []
        for j in range(len(lst)):
            if (i >> j) & 1 == 1:
                sublst.append(lst[j])
        lstlst.append(sublst)
    return lstlst


# 入力
H, W, K = map(int, input().split())
S = [[int(x) for x in list(input())] for h in range(H)]

# 横方向にカットする位置の列挙
cutlst = all_sublist(list(range(1, H)))

# 横方向の切り方を動かして切る数の合計の最小値を求める
cnt_min = 10**9 + 7
for cut in cutlst:
    # 横方向に切って圧縮したものをSSとする
    SS = []
    cut.append(H)
    start = 0
    for stop in cut:
        T = []
        for w in range(W):
            tmp = 0
            for h in range(start, stop):
                tmp += S[h][w]
            T.append(tmp)
        SS.append(T)
        start = stop
    H0 = len(SS)
    # K以上の成分があったらこのcutはパス
    if any([SS[h][w] > K for h in range(H0) for w in range(W)]):
        continue
    # 縦方向に切る数を数える
    cnt = len(cut) - 1
    left = [0 for h in range(H0)]
    right = [SS[h][0] for h in range(H0)]
    for w in range(1, W):
        left, right = right, [right[h] + SS[h][w] for h in range(H0)]
        leftOK = all([left[h] <= K for h in range(H0)])
        rightNG = any([right[h] > K for h in range(H0)])
        # すべての成分がK以下になるギリギリのところで切る
        if leftOK and rightNG:
            left = [0 for h in range(H0)]
            right = [SS[h][w] for h in range(H0)]
            cnt += 1
    cnt_min = min(cnt_min, cnt)
print(cnt_min)