Problem:


Score : 500 points

Problem Statement

We have a chocolate bar partitioned into H horizontal rows and W vertical columns of squares.

The square (i, j) at the i-th row from the top and the j-th column from the left is dark if S_{i,j} is 0, and white if S_{i,j} is 1.

We will cut the bar some number of times to divide it into some number of blocks. In each cut, we cut the whole bar by a line running along some boundaries of squares from end to end of the bar.

How many times do we need to cut the bar so that every block after the cuts has K or less white squares?

Constraints

1 \leq H \leq 10

1 \leq W \leq 1000

1 \leq K \leq H \times W

S_{i,j} is 0 or 1.

Input

Input is given from Standard Input in the following format:

H W K
S_{1,1}S_{1,2}...S_{1,W}
:
S_{H,1}S_{H,2}...S_{H,W}

Output

Print the number of minimum times the bar needs to be cut so that every block after the cuts has K or less white squares.

Sample Input 1

3 5 4
11100
10001
00111

Sample Output 1

2

For example, cutting between the 1-st and 2-nd rows and between the 3-rd and 4-th columns - as shown in the figure to the left - works.

Note that we cannot cut the bar in the ways shown in the two figures to the right.

Sample Input 2

3 5 8
11100
10001
00111

Sample Output 2

0

No cut is needed.

Sample Input 3

4 10 4
1110010010
1000101110
0011101001
1101000111

Sample Output 3

3



Sample input:
3 5 4
11100
10001
00111


Sample output:
2

Submission status: Runtime Error

Solution code:
import itertools
H, W, K = map(int,input().split())
S = [list(map(int,list(input()))) for _ in range(H)]
def check(k):
    if k <= K:
        return(True)
    else:
        return(False)
        
noans = 0
def make_lst(i):
    global noans, lst, havelst
    temp = S[0][i]
    for h in range(H-1):
        if y[h]:
            lst.append(temp)
            temp = S[h+1][i]
        else:
            temp += S[h+1][i]
    lst.append(temp)
    if check(max(lst)):
        havelst = 1
    else:
        noans = 1
               
def nocut(i):
    global cutnum, lst, havelst
    prelst = []
    temp = S[0][i]
    j = 0
    for h in range(H-1):
        if y[h]:
            lst[j] += temp
            prelst.append(temp)
            j += 1
            temp = S[h+1][i]
        else:
            temp += S[h+1][i]
    prelst.append(temp)
    lst[-1] += temp
    if check(max(lst)):
        return(True)
    else:
        cutnum += 1
        lst = prelst        
                 
ans = float("inf")
cutlst = []    
for y in itertools.product((0, 1), repeat=H-1):
    havelst = 0
    lst = []
    cutnum = sum(y)
    for x in range(W):
        if noans:
          	noans = 0
            break
        if havelst:
            nocut(x)
        else:
            make_lst(x)
    ans = min(cutnum, ans)
print(ans)

Submission status: Runtime Error

Solution code:
def add(j):
    for i in range(g):
        now[i] += c[i][j]
    for l in range(g):
        if now[l] > k:
            return False
    return  True

import sys
input=lambda :sys.stdin.readline().rstrip()

f_inf = float('inf')
c = [[0]*10 for _ in range(1005)]

h, w, k = map(int, input().split())
S = [[int(i) for i in input()] for _ in range(h)]

ans = f_inf
for div in range(1<<(h-1)):
    g = 0
    id = [0] * h
    for i in range(h):
        id[i] = g
        if (div >> i & 1):
            g += 1
    g += 1

    for i in range(g):
        for j in range(w):
            c[i][j] = 0
    for i in range(h):
        for j in range(w):
            c[id[i]][j] += int(S[i][j])
    ok = True
    for i in range(g):
        for j in range(w):
            if c[i][j] > k:
                ok = False
    if not ok: continue

    num = g-1
    now = [0]*g
    for j in range(w):
        if not add(j):
            ans += 1
            now = [0] * g
            add(j)
    ans = min(ans, num)
print(ans)

Submission status: Runtime Error

Solution code:
import sys
from bisect import *
from heapq import *
from collections import *
from itertools import *
from functools import *
from math import *

sys.setrecursionlimit(100000000)
input = lambda: sys.stdin.readline().rstrip()

H, W, K = map(int, input().split())
S = [input() for _ in range(H)]
mi = None

def max(iterable):
    ma = 0
    for i in iterable:
        ma = max(ma, i)
    return ma

for i in range(2 ** (H - 1)):
    # div[j] is true if row j and row j + 1 is divided
    div = [(i & (1 << j)) > 0 for j in range(H - 1)]
    group = [0] * H
    for j in range(H - 1):
        group[j + 1] = group[j] + 1 if div[j] else group[j]
    count = Counter()
    ans = div.count(True)
    ok = True
    for j in range(W):
        tmp = Counter()
        for k in range(H):
            if S[k][j] == '1':
                tmp[group[k]] += 1
        if max(tmp.values()) > K:
            ok = False
        elif max((tmp + count).values()) <= K:
            count += tmp
        else:
            count = tmp
            ans += 1
    if ok and (mi is None or ans < mi):
        mi = ans

print(mi)

Submission status: Runtime Error

Solution code:
import sys
from bisect import *
from heapq import *
from collections import *
from itertools import *
from functools import *
from math import *

sys.setrecursionlimit(100000000)
input = lambda: sys.stdin.readline().rstrip()

H, W, K = map(int, input().split())
S = [input() for _ in range(H)]
mi = None

for i in range(2 ** (H - 1)):
    # div[j] is true if row j and row j + 1 is divided
    div = [(i & (1 << j)) > 0 for j in range(H - 1)]
    group = [0] * H
    for j in range(H - 1):
        group[j + 1] = group[j] + 1 if div[j] else group[j]
    count = Counter()
    ans = div.count(True)
    ok = True
    for j in range(W):
        tmp = Counter()
        for k in range(H):
            if S[k][j] == '1':
                tmp[group[k]] += 1
        if max(tmp.values(), default=0) > K:
            ok = False
        elif max((tmp + count).values(), default=0) <= K:
            count += tmp
        else:
            count = tmp
            ans += 1
    if ok and (mi is None or ans < mi):
        mi = ans

print(mi)

Submission status: Runtime Error

Solution code:
import sys
from bisect import *
from heapq import *
from collections import *
from itertools import *
from functools import *
from math import *

sys.setrecursionlimit(100000000)
input = lambda: sys.stdin.readline().rstrip()

H, W, K = map(int, input().split())
S = [input() for _ in range(H)]
mi = None

for i in range(2 ** (H - 1)):
    # div[j] is true if row j and row j + 1 is divided
    div = [(i & (1 << j)) > 0 for j in range(H - 1)]
    group = [0] * H
    for j in range(H - 1):
        group[j + 1] = group[j] + 1 if div[j] else group[j]
    count = Counter()
    ans = div.count(True)
    ok = True
    for j in range(W):
        tmp = Counter()
        for g in group:
            tmp[g] = 0
        for k in range(H):
            if S[k][j] == '1':
                tmp[group[k]] += 1
        if max(tmp.values()) > K:
            ok = False
        elif max((tmp + count).values()) <= K:
            count += tmp
        else:
            count = tmp
            ans += 1
    if ok and (mi is None or ans < mi):
        mi = ans

print(mi)

Submission status: Runtime Error

Solution code:
import sys
from bisect import *
from heapq import *
from collections import *
from itertools import *
from functools import *
from math import *

sys.setrecursionlimit(100000000)
input = lambda: sys.stdin.readline().rstrip()

H, W, K = map(int, input().split())
S = [input() for _ in range(H)]
mi = None

for i in range((H - 1) ** 2):
    # div[j] is true if row j and row j + 1 is divided
    div = [(i & (1 << j)) > 0 for j in range(H - 1)]
    group = [0] * H
    for j in range(H - 1):
        group[j + 1] = group[j] + 1 if div[j] else group[j]
    count = Counter()
    ans = div.count(True)
    ok = True
    for j in range(W):
        tmp = Counter()
        for k in range(H):
            if S[k][j] == '1':
                tmp[group[k]] += 1
        if max(tmp.values()) > K:
            ok = False
        elif max((tmp + count).values()) <= K:
            count += tmp
        else:
            count = tmp
            ans += 1
    if ok and (mi is None or ans < mi):
        mi = ans

print(mi)

Submission status: Runtime Error

Solution code:
from itertools import product
import numpy as np

h, w, k = list(map(int, input().split()))
s = [list(map(int, list(input()))) for i in range(h)]
INF = float("inf")
ans = INF
for bits in product([0, 1], repeat=h-1):
    cnt = sum(bits)
    cuts = [0]+[i + 1 for i, x in enumerate(bits) if x == 1]+[h]
    data = [[0]*w for _ in range(len(cuts)-1)]
    for i in range(len(cuts)-1):
        target = s[cuts[i]:cuts[i+1]]
        for tt in target:
            for j, t in enumerate(tt):
                data[i][j] += t
    check = [[0]*(w+1) for _ in range(len(data))]
    flag = False
    for j in range(w):
        if flag:
            continue
        change = False
        for i in range(len(data)):
            if check[i][j] + data[i][j] > k:
                change = True
                break
        if change:
            for i in range(len(data)):
                if data[i][j] <= k:
                    check[i][j+1] = data[i][j]
                else:
                    flag = True
                    break
            cnt += 1
        else:
            for i in range(len(data)):
                check[i][j+1] = check[i][j] + data[i][j]
    if flag:
        continue
    ans = min(ans, cnt)
print(ans)

Submission status: Runtime Error

Solution code:
def main():
    from itertools import product
    
    H, W, K = map(int, input().split())
    S = [input() for _ in range(H)]
    S_T = [[int(s[w]) for s in S] for w in range(W)]
    sumS = sum(map(sum, S_T))
    ans = (H - 1) * (W - 1)
    
    if sumS <= K:
        print(0)
    else:
        for i in product([True, False], repeat=H-1):
            cnt = sum(i)
            if cnt >= ans:
                continue
            M = [[0]]
            for j, k in enumerate(i):
                if k:
                    M.append([])
                M[-1].append(j+1)
            A = [0] * len(M)
            for s_t in S_T:
                for l, m in enumerate(M):
                    A[l] += sum(s_t[i] for i in m)
                if any(a > K for a in A):
                    cnt += 1
                    if cnt >= ans:
                        break
                    A = [sum(s_t[i] for i in m) for m in M]
                    if any(a > K for a in A):
                        cnt = ans + 1
                        break
            ans = min(cnt, ans)
        print(ans)

if __name__ == '__main__'
    main()

Submission status: Runtime Error

Solution code:
H, W, K = [int(i) for i in input().split()]
C = [[int(i) for i in list(input())] for _ in range(H)]

def minisolve(left, cut, n):
    a = [0] * n
    i = 0
    while left < W:
        for t in range(H):
            if t >= cut[i]:
                i += 1
            if C[t][left]:
                a[i] += 1
                if a[i] > K:
                    return left
        left += 1
        i = 0

ans = 10**18
N = H-1
for bit in range(1<<N):
    n = 1
    cut = []
    for i in range(N):
        if 1 & bit>>i:
            n += 1
            cut.append(i+1)
    cut.append(H)

    left = 0
    res = 0
    while True:
        left = minisolve(left, cut, n)
        if left:
            break
        else:
            res += 1
    res += n-1
    ans = min(ans, res)

print(ans)

Submission status: Runtime Error

Solution code:
from collections import defaultdict
from itertools import product
 
H, W, K = map(int, input().split())
S = [input() for _ in range(H)]
 
i = 0
while i < len(S):
  if '1' in S[i]:
    i += 1
  else:
    del S[i]
H = len(S)
 
C = [[int(s[i]) for s in S] for i in range(W)]#列を一括りにする

total = sum(sum(c) for c in C)#すべての値の合計を算出
 
answer = H * W
for X in product([False, True], repeat=H-1):#Hは行数
  #あるXについて一回目のfor文が回る
  ans = sum(X)#Trueの数を換算
  if ans > answer:
    continue
  M = [[0]]
  for i, x in enumerate(X):
    if x:#Trueなら実行
      M.append([])#Trueの数の配列が作成される
    M[-1].append(i+1)#一番最後にその番目をappendする
  D = [0] * len(M)#初期値を設定
  for c in C:
    for k, m in enumerate(M):
      D[k] += sum(c[i] for i in m)#k番目の要素に足していく
      #Dにどんどん代入することによってどの列まで足すことができるか算出することができる
    if any(d > K for d in D):#一つでもKを超えていたら
      ans += 1
      if ans > answer:
        break
      D = [sum(c[i] for i in m) for m in M]#Dの更新(1番最初のDに戻る)
      if any(d > K for d in D):#一つでもKを超えていたら
        ans = answer + 1#ansの更新
        break
  answer = min(answer, ans)

print(answer)

Submission status: Runtime Error

Solution code:
from collections import defaultdict
from itertools import product
 
H, W, K = map(int, input().split())
S = [input() for _ in range(H)]
 
i = 0
while i < len(S):
  if '1' in S[i]:
    i += 1
  else:
    del S[i]
H = len(S)
 
C = [[int(s[i]) for s in S] for i in range(W)]#列を一括りにする
print(C)
total = sum(sum(c) for c in C)#すべての値の合計を算出
 

answer = H * W
for X in product([False, True], repeat=H-1):#Hは行数
  #あるXについて一回目のfor文が回る
  ans = sum(X)#Trueの数を換算
  if ans > answer:
    continue
  M = [[0]]
  for i, x in enumerate(X):
    if x:#Trueなら実行
      M.append([])#Trueの数の配列が作成される
    M[-1].append(i+1)#一番最後にその番目をappendする
  D = [0] * len(M)#初期値を設定
  for c in C:
    for k, m in enumerate(M):
      D[k] += sum(c[i] for i in m)#k番目の要素に足していく
      #Dにどんどん代入することによってどの列まで足すことができるか算出することができる
    if any(d > K for d in D):#一つでもKを超えていたら
      ans += 1
      if ans > answer:
        break
      D = [sum(c[i] for i in m) for m in M]#Dの更新(1番最初のDに戻る)
      if any(d > K for d in D):#一つでもKを超えていたら
        ans = answer + 1#ansの更新
        break
  answer = min(answer, ans)

print(answer)

Submission status: Runtime Error

Solution code:
def main():
    import numpy as np
    h,w,k = map(int,input().split())
    l = [list(input()) for i in range(h)]

    def check(lis):
        
        num = np.zeros(len(lis))
        ans = 0
        for i in range(w):
            num2 = np.zeros(len(lis))
            for j in range(h):
                if l[j][i] == "1":
                    num2[d[j]] += 1
            
            if np.max(num2) > k:
                return float("INF")
            else:
                num += num2
            if np.max(num) > k:
                ans += 1
                num = num2
            
        return ans

    ans = 10**9

    for i in range(2**(h-1)):
        count = 0
        lis1 = []
        d = []
        for j in range(h-1):
            d.append(count)
            if (i >> j) & 1:
                lis1.append(j)
                count += 1
        lis1.append(count+1)
        
        ans = min(ans,count+check(lis1))
        
    print(ans)
if __name__ == "__main__":
    main()

Submission status: Runtime Error

Solution code:
import sys
from itertools import product
input = sys.stdin.readline
sys.setrecursionlimit(10**7)
h, w, k = map(int, input().split())
CHOCO = [list(map(int, input())) for _ in range(h)]
INF = 10**5

it = ["01"]*(h-1)
ans = INF
for x in product(*it):

    cnt = sum(map(int, x))

    agg = [[0]*(w) for _ in range(cnt+1)]
    *ls, = map(int, x+('1',))
    for i in range(w):
        prev = c = 0
        for j, split in enumerate(ls):
            if split:
                agg[c][i] = prev+CHOCO[j][i]
                prev = 0
                c += 1
            else:
                prev += CHOCO[j][i]

    tmp = [0]*(cnt+1)
    for xyz in zip(*agg):
        cannot_split = False
        can_continue = True
        for i, x in enumerate(xyz):
            if x > k:
                cannot_split = True
                break
            if x+tmp[i] > k:
                can_continue = False
                break

        if cannot_split:
            break

        if can_continue:
            for i, x in enumerate(xyz):
                tmp[i] += x
                continue
        else:
            for i, x in enumerate(xyz):
                tmp[i] = x
            cnt += 1

    if cannot_split:
        continue

    ans = min(ans, cnt)
print(ans)

Submission status: Runtime Error

Solution code:
import sys
from itertools import product
input = sys.stdin.readline
sys.setrecursionlimit(10**7)
h, w, k = map(int, input().split())
CHOCO = [list(map(int, input())) for _ in range(h)]
INF = 10**5

it = ["01"]*(h-1)
ans = INF
for x in product(*it):
    cnt = sum(map(int, x))
    agg = [[0]*(w) for _ in range(cnt+1)]
    *ls, = map(int, x+('1',))
    for i in range(w):
        prev = c = 0
        for j, split in enumerate(ls):
            if split:
                agg[c][i] = prev+CHOCO[j][i]
                prev = 0
                c += 1
            else:
                prev += CHOCO[j][i]

    tmp = [0]*(cnt+1)
    for xyz in zip(*agg):
        cannot_split = False
        can_continue = True
        for i, x in enumerate(xyz):
            if x > k:
                cannot_split = True
                break
            if x+tmp[i] > k:
                can_continue = False
                break

        if cannot_split:
            break

        if can_continue:
            for i, x in enumerate(xyz):
                tmp[i] += x
                continue
        else:
            for i, x in enumerate(xyz):
                tmp[i] = x
            cnt += 1

    if cannot_split:
        continue

    ans = min(ans, cnt)
print(ans)

Submission status: Runtime Error

Solution code:
from itertools import product
# h, w, k = map(int, input().split())
# CHOCO = [list(map(int, input())) for _ in range(h)]
h, w, k = map(int, input().split())
CHOCO = [list(map(int, input())) for _ in range(h)]
INF = 10**5

it = ["01"]*(h-1)
ans = INF
for x in product(*it):
    cnt = sum(map(int, x))
    agg = [[0]*(w) for _ in range(cnt+1)]
    *ls, = map(int, x+('1',))
    for i in range(w):
        prev = c = 0
        for j, split in enumerate(ls):
            if split:
                agg[c][i] = prev+CHOCO[j][i]
                prev = 0
                c += 1
            else:
                prev += CHOCO[j][i]

    tmp = [0]*(cnt+1)
    cannot_split = False

    start = time.time()
    for xyz in zip(*agg):
        cannot_split = False
        can_continue = True
        for i, x in enumerate(xyz):
            if x > k:
                cannot_split = True
                break
            if x+tmp[i] > k:
                can_continue = False
                break

        if cannot_split:
            break

        if can_continue:
            for i, x in enumerate(xyz):
                tmp[i] += x
                continue
        else:
            for i, x in enumerate(xyz):
                tmp[i] = x
            cnt += 1

    if cannot_split:
        continue

    ans = min(ans, cnt)
print(ans)

Submission status: Runtime Error

Solution code:
import numpy as np

h, w, k = map(int, input().split())
s = []
for i in range(h):
    string = input()
    temp = []
    for j in range(w):
        temp.append(int(string[j]))
    s.append(temp)

s_arr = np.array(s)

ans = 10**9
for i in range(2**(h-1)):
    bin_str = format(i, '0'+str(h-1)+'b')
    kouryo = np.array([[0 for _ in range(w)]])
    cnt = 0
    start = 0
    new = 0
    for j in range(h-1):
        if bin_str[j] == '1':
            cnt += 1
            new = s_arr[start:j+1].sum(axis=0, keepdims=True)
            if np.any(new>k):
                new = -1
                break
            kouryo = np.concatenate((kouryo, new), axis=0)
            start=j+1
    if new == -1: continue
    kouryo = np.concatenate((kouryo, s_arr[start:].sum(axis=0, keepdims=True)), axis=0)

    wa = kouryo[:, 0]
    for j in range(1, w):
        wa = wa + kouryo[:, j]
        if np.any(wa>k):
            cnt += 1
            wa = kouryo[:, j]
    ans = min(ans, cnt)
print(ans)

Submission status: Runtime Error

Solution code:
import numpy as np

h, w, k = map(int, input().split())
s = []
for i in range(h):
    string = input()
    temp = []
    for j in range(w):
        temp.append(int(string[j]))
    s.append(temp)

s_arr = np.array(s)

ans = 10**9
for i in range(2**(h-1)):
    bin_str = format(i, '0'+str(h-1)+'b')
    kouryo = np.array([[0 for _ in range(w)]])
    cnt = 0
    start = 0
    for j in range(h-1):
        if bin_str[j] == '1':
            cnt += 1
            new = s_arr[start:j+1].sum(axis=0, keepdims=True)
            if np.any(new>k):
                new = 0
                break
            kouryo = np.concatenate((kouryo, new), axis=0)
            start=j+1
    if new == 0: continue
    kouryo = np.concatenate((kouryo, s_arr[start:].sum(axis=0, keepdims=True)), axis=0)

    wa = kouryo[:, 0]
    for j in range(1, w):
        wa = wa + kouryo[:, j]
        if np.any(wa>k):
            cnt += 1
            wa = kouryo[:, j]
    ans = min(ans, cnt)
print(ans)

Submission status: Runtime Error

Solution code:
#include <bits/stdc++.h>
#define rep(i,n) for (int i=0; i<(n); ++i)
using namespace std;
using ll = long long;
using P = pair<int, int>;

const int INF = 1001001001;

int c[10][1005];

int main(){
    int h, w, k;
    cin >> h >> w >> k;
    vector<string> s(h);
    rep(i,h) cin >> s[i];
    int ans = INF;
    rep(bit,1<<(h-1)){
        int n = 0;
        vector<int> id(h);
        rep(i,h){
            id[i] = n;
            if (bit>>i&1) ++n;
        }
        ++n;
        rep(i,n)rep(j,w) c[i][j] = 0;
        rep(i,h)rep(j,w) c[id[i]][j] += (s[i][j]-'0');
        bool ok = true;
        rep(i,n)rep(j,w) if (c[i][j] > k) ok = false;
        if (!ok) continue;

        int num = n-1;
        if (num >= ans) continue;
        vector<int> now(n);
        auto add = [&](int j){
            rep(i,n) now[i] += c[i][j];
            rep(i,n) if (now[i] > k) return false;
            return true;
        };
        rep(j,w){
            if (!add(j)){
                num++;
                now = vector<int>(n);
                add(j);
            }
        }
        ans = min(ans, num);
    }
    cout << ans << endl;
    return 0;
}

Submission status: Runtime Error

Solution code:

import numpy as np

h,w,k = map(int,input().split())
S = [list(input()) for _ in range(h)]

res = 10**6
for div in range(2**(h-1)):
    cut = []
    for i in range(h-1):
        if ((div >> i) & 1):
            cut.append(i+1)
    fr = 0
    part = []
    for i in range(len(cut)):
        to = cut[i]
        part.append(S[fr:to])
        fr = to
    else:
        part.append(S[fr:])
    comp_arr = []
    for p in part:
        p_ = np.array(p).astype(np.int)
        comp_arr.append(p_.sum(axis=0))  
    cnt = len(cut)
    tank = [0]*len(comp_arr)    
    for m in range(w):
        for n in range(len(comp_arr)):
            tank[n] += comp_arr[n][m]
        if any([c>k for c in tank]):
            cnt += 1
            for n in range(len(comp_arr)):
                tank[n] = comp_arr[n][m]
    res = min(res, cnt)
print(res)

Submission status: Runtime Error

Solution code:
import numpy as np

h,w,k = map(int,input().split())
S = [list(input()) for _ in range(h)]

res = 10**6
for div in range(2**(h-1)):
    cut = []
    for i in range(h-1):
        if ((div >> i) & 1):
            cut.append(i+1)
    fr = 0
    part = []
    for i in range(len(cut)):
        to = cut[i]
        part.append(S[fr:to])
        fr = to
    else:
        part.append(S[fr:])
    comp_arr = []
    for p in part:
        p_ = np.array(p).astype(np.int)
        comp_arr.append(p_.sum(axis=0))
    comp_arr_T = np.array(comp_arr).T
    
    cnt = len(cut)

    tank = [0]*len(comp_arr)
    
    for m in range(w):
        for n in range(len(comp_arr)):
            tank[n] += comp_arr[n][m]

        if any([c>k for c in tank]):
            cnt += 1
            for n in range(len(comp_arr)):
                tank[n] = comp_arr[n][m]

    res = min(res, cnt)
print(res)

Submission status: Runtime Error

Solution code:
import numpy as np

h,w,k = map(int,input().split())
S = [list(input()) for _ in range(h)]

res = float('inf')
for div in range(2**(h-1)):
    cut = []
    for i in range(h-1):
        if ((div >> i) & 1):
            cut.append(i+1)
    fr = 0
    part = []
    for i in range(len(cut)):
        to = cut[i]
        part.append(S[fr:to])
        fr = to
    else:
        part.append(S[fr:])
    comp_arr = []
    for p in part:
        p_ = np.array(p).astype(np.int)
        comp_arr.append(p_.sum(axis=0))
    comp_arr_T = np.array(comp_arr).T
    
    cnt = len(cut)

    tank = [0]*len(comp_arr)
    
    for m in range(w):
        for n in range(len(comp_arr)):
            tank[n] += comp_arr[n][m]

        if any([c>k for c in tank]):
            cnt += 1
            for n in range(len(comp_arr)):
                tank[n] = comp_arr[n][m]

    res = min(res, cnt)
print(res)

Submission status: Runtime Error

Solution code:
import numpy as np

h,w,k = map(int,input().split())
S = [list(input()) for _ in range(h)]

res = float('inf')
# bit全探索
for div in range(2**(h-1)):
    cut = []
    for i in range(h-1):
        if ((div >> i) & 1):
            cut.append(i+1)
    fr = 0
    part = []
    for i in range(len(cut)):
        to = cut[i]
        part.append(S[fr:to])
        fr = to
    else:
        part.append(S[fr:])
    comp_arr = []
    for p in part:
        p_ = np.array(p).astype(np.int)
        comp_arr.append(p_.sum(axis=0))
    comp_arr_T = np.array(comp_arr).T
    
    cnt = len(cut)

    tank = [0]*len(comp_arr)
    
    for m in range(w):
        for n in range(len(comp_arr)):
            tank[n] += comp_arr[n][m]

        if any([c>k for c in tank]):
            cnt += 1
            for n in range(len(comp_arr)):
                tank[n] = comp_arr[n][m]

    res = min(res, cnt)
print(res)

Submission status: Runtime Error

Solution code:
def get_sum(x1, x2, y1, y2):
    return acc[x2][y2] - acc[x1][y2] - acc[x2][y1] + acc[x1][y1]


h, w, k = map(int, input().split())
s = [[int(c) for c in input()] for i in range(h)]

acc = [[0 for j in range(w + 1)] for i in range(h + 1)]
for i in range(h):
    for j in range(w):
        acc[i + 1][j + 1] = acc[i][j + 1] + acc[i + 1][j] - acc[i][j] + s[i][j]

min_div_cnt = 10 ** 18

for h_div in range(1 << (h - 1)):
    h_ranges = []
    cur_begin = 0
    for i in range(h - 1):
        if (h_div >> i) & 1:
            h_ranges.append([cur_begin, i + 1])
            cur_begin = i + 1
    h_ranges.append([cur_begin, h])
    h_div_cnt = len(h_ranges) - 1

    max_hchoco_cnt = 0
    tgt_h_range = []
    for h_range in h_ranges:
        hchoco_cnt = get_sum(h_range[1], h_range[0], w, 0)
        if hchoco_cnt > max_hchoco_cnt:
            max_hchoco_cnt = hchoco_cnt
            tgt_h_range = h_range

    cur_begin = 0
    v_div_cnt = 0
    is_valid = True
    for i in range(0, w):
        cur_cnt = get_sum(tgt_h_range[1], tgt_h_range[0], i, cur_begin)
        next_cnt = get_sum(tgt_h_range[1], tgt_h_range[0], i + 1, cur_begin)
        if next_cnt - cur_cnt > k:
            is_valid = False
            break
        if cur_cnt <= k and next_cnt > k:
            cur_begin = i
            v_div_cnt += 1

    if is_valid:
        min_div_cnt = min(min_div_cnt, h_div_cnt + v_div_cnt)

print(min_div_cnt)

Submission status: Runtime Error

Solution code:
import sys


def input():
    return sys.stdin.readline().strip()


def get_sum(x1, x2, y1, y2):
    return acc[x2][y2] - acc[x1][y2] - acc[x2][y1] + acc[x1][y1]


h, w, k = map(int, input().split())
s = [[int(c) for c in input()] for i in range(h)]

acc = [[0 for j in range(w + 1)] for i in range(h + 1)]
for i in range(h):
    for j in range(w):
        acc[i + 1][j + 1] = acc[i][j + 1] + acc[i + 1][j] - acc[i][j] + s[i][j]

min_div_cnt = 10 ** 18

for h_div in range(1 << (h - 1)):
    h_ranges = []
    cur_begin = 0
    for i in range(h - 1):
        if (h_div >> i) & 1:
            h_ranges.append([cur_begin, i + 1])
            cur_begin = i + 1
    h_ranges.append([cur_begin, h])
    h_div_cnt = len(h_ranges) - 1

    max_hchoco_cnt = 0
    tgt_h_range = []
    for h_range in h_ranges:
        hchoco_cnt = get_sum(h_range[1], h_range[0], w, 0)
        if hchoco_cnt > max_hchoco_cnt:
            max_hchoco_cnt = hchoco_cnt
            tgt_h_range = h_range

    cur_begin = 0
    v_div_cnt = 0
    is_valid = True
    for i in range(0, w):
        cur_cnt = get_sum(tgt_h_range[1], tgt_h_range[0], i, cur_begin)
        next_cnt = get_sum(tgt_h_range[1], tgt_h_range[0], i + 1, cur_begin)
        if next_cnt - cur_cnt > k:
            is_valid = False
            break
        if cur_cnt <= k and next_cnt > k:
            cur_begin = i
            v_div_cnt += 1

    if is_valid:
        min_div_cnt = min(min_div_cnt, h_div_cnt + v_div_cnt)

print(min_div_cnt)