fork download
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
typedef long long int ll;
ll t, n, m, mat[50][50], minim_rowarr[50][50][50], ans_row[50][50][50], ans_col[50][50][50], minim_colarr[50][50][50], ans[50][50][50][50], minim_ans[50][50][50][50];
ll solve_row(int row, int a, int b)
{
	if (ans_row[row][a][b] != -1)
		return ans_row[row][a][b];
	if (a == b)
		return 0;
	ll minim = 110000;
	for (int i = a; i <= b; i++)
		minim = min(minim, mat[row][i]);
	minim_rowarr[row][a][b] = minim;
	minim_ans[row][a][row][b] = minim;
	ll maxim = 0;
	for (int i = a; i < b; i++)
	{
		maxim = max(solve_row(row, a, i)+solve_row(row, i+1, b), maxim);
	}
	ans_row[row][a][b] = maxim+minim;
	ans[row][a][row][b] = maxim+minim;
	return (maxim+minim);
}

ll solve_col(int col, int a, int b)
{
	if (ans_col[col][a][b] != -1)
		return ans_col[col][a][b];
	if (a == b)
		return 0;
	ll minim = 110000;
	for (int i = a; i <= b; i++)
		minim = min(minim, mat[i][col]);
	minim_colarr[col][a][b] = minim;
	minim_ans[a][col][b][col] = minim;
	ll maxim = 0;
	for (int i = a; i < b; i++)
	{
		maxim = max(solve_col(col, a, i)+solve_col(col, i+1, b), maxim);
	}
	ans_col[col][a][b] = maxim+minim;
	ans[a][col][b][col] = maxim+minim;
	return (maxim+minim);
}

int main()
{
	ios::sync_with_stdio(false);
	cin>>t;
	for (int i = 1; i <= t; i++)
	{
		memset(ans_row, -1, sizeof(ans_row));
		memset(ans_col, -1, sizeof(ans_col));
		memset(ans, 0, sizeof(ans));
		memset(minim_ans, 0, sizeof(minim_ans));
		memset(minim_rowarr, 0, sizeof(minim_rowarr));
		memset(minim_colarr, 0, sizeof(minim_colarr));
		memset(mat, 0, sizeof(mat));
		cin>>n>>m;
		for (int j = 1; j <= n; j++)
		{
			for (int k = 1; k <= m; k++)
			{
				cin>>mat[j][k];
			}
			solve_row(j, 1, m);
		}
		for (int j = 1; j <= m; j++)
		{
			solve_col(j, 1, n);
		}
		for (int j = 1; j <= n; j++)
		{
			for (int k = 1; k <= m; k++)
			{
				for (int l = j-1; l >= 1; l--)
				{
					for (int y = k-1; y >= 1; y--)
					{
						ll maxim_ans = 0;
						ll minim = min(minim_ans[l][y+1][j][k], minim_ans[l][y][j][y]);
						minim_ans[l][y][j][k] = minim;
						for (int z = j; z > l; z--)
						{
							maxim_ans = max(maxim_ans, (ans[l][y][z-1][k]+ans[z][y][j][k]));
						}
						for (int z = k; z > y; z--)
						{
							maxim_ans = max(maxim_ans, (ans[l][y][j][z-1]+ans[l][z][j][k]));
						}
						ans[l][y][j][k] = maxim_ans+minim;
					}
				}
			}	
		}
		ll ans1 = ans[1][1][n][m];
		cout<<"Case #"<<i<<": "<<ans1<<"\n";
	}
}
Success #stdin #stdout 0s 116800KB
stdin
Standard input is empty
stdout
Standard output is empty