It is only now that I have read the wrong question during the game. . . Thought that the number of 1s to be connected cannot exceed
?
Topic:
Give you a rectangle, then 0 black grids and 1 white grid. Now you can cut this rectangle horizontally or vertically so that the number of white blocks in each block is <= k.
Idea: I have
encountered many such problems.
Since the range of one coordinate axis is small and the other is large, it is possible to binary enumerate the coordinate axis with a small range. Then iterate through the column judgment.
Because I didn't bring my mind when writing, various bugs were adjusted for a long time.
Then, in fact, we can directly calculate the two-dimensional prefix sum of the pre-processing, so that the constant will be smaller, who made me lose my mind, so be it.
Complexity
int w[20][2000];
int x[2000][20];
bool vis[1005];
//总体思路,先把行切开,再去切列
int main(){
int n = read(),m = read(),k = read();
rep(i,1,n){
rep(j,1,m){
char c;
cin >> c;
w[i][j] = c -'0';
x[j][i] = x[j][i-1] + w[i][j];//预处理每列的前缀和
}
}
int S = (1 << (n));
int ans = INF;
for(int q = 1;q <= S-1;++ q){//二进制枚举每种切割情况,第i位为1,则从第(i+1)行下面切一刀
int p = q;
p |= (1<<(n-1));//我们为了处理方便,在最后一行后面留一刀,最后减掉即可
vector<int> Q[20];
int tot = 0;
int inx = 1;//控制每个连通块的行
bool r = 1;
for(int i = 0;i < n;++i){
if((p>>i)&1){
tot ++;
rep(j,1,m){
int d = x[j][i+1] - x[j][inx-1];
if(d > k) {r = 0;break;}
Q[tot].push_back(d);
}
inx = i + 2;
}
if(r == 0) break;
}
if(r == 0) continue;
int h = 0;
/*
这儿判断列需要切几刀,我一开始想着贪心去切,取切列的最大刀数,可是一直有5组Wa,
后来相出一种情况,发现不对劲,然后只能m*n判断了,额....刚才似乎是n*m,复杂度一样嘛......
*/
int Sum[12] = {0};
for(int i = 0;i <= m-1;++i){
bool op = 1;
for(int j = 1;j <= tot;++j){
Sum[j] += Q[j][i];
if(Sum[j]>k){op = 0;break;}
}
if(!op){
h ++;
rep(j,1,tot) Sum[j] = Q[j][i];
}
}
ans = min(ans,tot-1+h);
}
if(ans == INF) ans = 0;
cout << ans;
}