/*
f[i][j] = 第i天以j结尾的最大值
取第i行的(j-k+1,j)
取第i+1行的(j-k+1,j)
f[i][j] =
*/
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 5;
int f[2][N], pre[N], nxt[N];
vector<int>a[N];
int n, m, k;

int Get(int l, int r, int id) {
	if (l > r)
		return 0;
	return a[id][r] - a[id][l - 1];
}

int main() {
	cin >> m >> n >> k;
	for (int i = 1; i <= n; i++) {
		a[i].push_back(0);
		for (int j = 1; j <= m; j++) {
			int x;
			cin >> x;
			a[i].push_back(x);
			a[i][j] += a[i][j - 1];
		}
	}
	//先算第一行
	for (int i = 1; i <= m; i++) {
		f[1][i] = Get(max(i - k + 1, 1), i, 1);
	}
	if (n > 1) {
		//算第二行
		for (int i = 1; i <= m; i++) {
			f[1][i] += Get(max(i - k + 1, 1), i, 2);
		}
		//pre
		for (int i = 1; i <= m; i++) {
			pre[i] = max(pre[i - 1], f[1][i]);
		}
		//nxt
		for (int i = m; i >= 1; i--) {
			nxt[i] = max(nxt[i + 1], f[1][i]);
		}
	}
	for (int i = 2; i <= n; i++) {
		int pos1 = i % 2;
		int pos2 = pos1 ^ 1;
		for (int j = 1; j <= m; j++) {
			f[pos1][j] = Get(max(1, j - k + 1), j, i);
			//如果上一行取得数在前面,不重合
			f[pos1][j] = max(f[pos1][j], pre[max(0, j - k)] + Get(max(1, j - k + 1), j, i));
			//如果上一行取的数在后面,不重合
			f[pos1][j] = max(f[pos1][j], nxt[min(j + k, m + 1)] + Get(max(1, j - k + 1), j, i));
			//重叠部分
			for (int t = j - 1; t >= max(1, j - k + 1); t--) {
				f[pos1][j] = max(f[pos1][j], f[pos2][t] + Get(t + 1, j, i));
			}
			for (int t = j + 1; t <= min(m, j + k - 1); t++) {
				f[pos1][j] = max(f[pos1][j], f[pos2][t] + Get(max(1, j - k + 1), max(0, t - k), i));
			}
		}
		if (i != n) {
			for (int j = 1; j <= m; j++)
				f[pos1][j] += Get(max(1, j - k + 1), j, i + 1);
			for (int j = 1; j <= m; j++)
				pre[j] = max(pre[j - 1], f[pos1][j]);
			for (int j = m; j >= 1; j--)
				nxt[j] = max(nxt[j + 1], f[pos1][j]);
		}
	}
	int pos1 = n % 2, res = 0;
	for (int i = 1; i <= m; i++) {
		res = max(res, f[pos1][i]);
	}
	cout << res << endl;
	return 0;
}

0 comments

No comments so far...