各アイテムは独立しているため、個別に処理できます
1行の場合、完全な絵を描いた後、絵は最高のものでなければなりません(それより良いものはありません)ので、列挙番号の開始点がシフトされます
異なるバー間の関係は、バックパックのグループ化です。。
コード:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int ff[5555],fff[5555],g[5555],tu[55][55],qsum1[55],qsum0[55],f[55][55],n,m,t,i,j,k,l;
int main()
{
scanf("%d%d%d",&n,&m,&t);
for(i=1;i<=t;i++)ff[i]=-999999999;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++){scanf("%c",&tu[i][j]);while(tu[i][j]!='0'&&tu[i][j]!='1')scanf("%c",&tu[i][j]); }
}
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
fff[j]=-999999999;
memset(qsum1,0,sizeof(qsum1));
memset(qsum0,0,sizeof(qsum0));
memset(g,0,sizeof(g));
memset(f,0,sizeof(f));
for(j=1;j<=m;j++)
{
qsum1[j]=qsum1[j-1]+ (tu[i][j]=='0'?0:1);
qsum0[j]=qsum0[j-1]+ (tu[i][j]=='1'?0:1);
}
for(j=1;j<=m;j++)
for(k=0;k<j;k++)
for(l=1;l<=m;l++)
{
f[j][l]=max(f[k][l-1]+max(qsum1[j]-qsum1[k],qsum0[j]-qsum0[k]),f[j][l]);
}
for(j=1;j<=m;j++)
{
for(k=1;k<=m;k++)
{
g[j]=max(g[j],f[k][j]);
}
}
for(j=1;j<=t;j++)
{
for(k=1;k<=m;k++)
{
if(j-k>=0)fff[j]=max(ff[j-k]+g[k],fff[j]);
}
}
for(j=1;j<=t;j++)ff[j]=max(ff[j],fff[j]);
}
printf("%d",ff[t]);
}