第一眼没看出来emmm...
所以就先想只有一条木板怎么做 即\(f[i][j]\)表示前\(i\)个格子刷\(j\)次最多能刷正确多少个格子
然后很容易就能想到n条木板就可以将其进行01背包来算最多能刷正确有多少个格子
因为每个格子最多刷一次 所以枚举\(j\)时\(j\)得小于等于\(i\)
#include<bits/stdc++.h>
using namespace std;
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)<(y)?(x):(y))
const int N=50+5,M=2500+5,inf=0x3f3f3f3f,P=19650827;
int n,m,t,ans=0,sum[N],f[N][M],nw[N][N];
char S[N];
template <class t>void rd(t &x){
x=0;int w=0;char ch=0;
while(!isdigit(ch)) w|=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
x=w?-x:x;
}
int main(){
freopen("in2.txt","r",stdin);
//freopen("xor.out","w",stdout);
rd(n),rd(m),rd(t);
memset(f,0,sizeof(f));
for(int x=1;x<=n;++x){
scanf("%s",S+1);
for(int i=1;i<=m;++i) sum[i]=sum[i-1]+(S[i]=='1');
for(int i=1;i<=m;++i)//前i个格子
for(int j=1;j<=i;++j){//涂j次
nw[i][j]=0;
for(int k=0;k<i;++k)//由前k个格子转移过来
nw[i][j]=Max(nw[i][j],nw[k][j-1]+Max(sum[i]-sum[k],i-k-(sum[i]-sum[k])));
}
for(int i=1;i<=t;++i)
for(int j=1;j<=Min(i,m);++j)
f[x][i]=Max(f[x][i],f[x-1][i-j]+nw[m][j]);
}
for(int i=1;i<=t;++i) ans=Max(ans,f[n][i]);
printf("%d",ans);
return 0;
}