f[i][j][k]表示前i行,最后一行前j个,选k次最优解
ntr[i][j][2]表示当前行区间i~j涂0或1所能刷的正确格子
#include <cstdio> #define N 51 #define M 2501 #define max(x, y) ((x) > (y) ? (x) : (y)) char s[N]; int n, m, t, ans; int ntr[N][N][2], f[N][N][M]; //f[i][j][k]表示前i行,最后一行前j个,选了k次的最优解 int main() { int i, j, k, l; scanf("%d %d %d", &n, &m, &t); for(i = 1; i <= n; i++) { scanf("%s", s + 1); for(j = 1; j <= m; j++) for(k = j; k <= m; k++) { ntr[j][k][0] = ntr[j][k - 1][0] + (s[k] == '0'); ntr[j][k][1] = ntr[j][k - 1][1] + (s[k] == '1'); } for(j = 0; j <= m; j++) for(k = 1; k <= t; k++) { f[i][j][k] = !j ? f[i - 1][m][k] : f[i][j - 1][k]; for(l = 0; l < j; l++) { f[i][j][k] = max(f[i][j][k], f[i][l][k - 1] + ntr[l + 1][j][0]); f[i][j][k] = max(f[i][j][k], f[i][l][k - 1] + ntr[l + 1][j][1]); } ans = max(ans, f[i][j][k]); } } printf("%d ", ans); return 0; }