#include <cstdio>
#include <string>
#include <iostream>
#include <cstring>
#include <ctime>
 
using namespace std;
 
const int N = 31;
const int MAXSIZE = 500000;
 
int bitmasks[MAXSIZE];
int next_fib[MAXSIZE][2];
int Fib[N+1], cnt = 0;
 
int getValue( int x ) {
	int result = 0;
	for( int i = 0; i <= N; i ++ )
		if( x & (1 << i) )
			result += Fib[i];
	return result;
}
 
void go( int idx, int cur ) {
	if( idx > N ) return;
	int g = getValue(cur);
	bitmasks[g] = cur;
	next_fib[g][0] = getValue((cur << 1));
	next_fib[g][1] = getValue((cur << 1) + 1);
	if( idx != N ) {
		if( cur & 3 )
			go( idx + 1, cur * 2 );
		else {
			go( idx + 1, cur * 2 );
			go( idx + 1, cur * 2 + 1 );
		}
	} else {
		cnt ++;
	}
}
 
void pre_process() {
	int cl = clock();
	Fib[0] = 1;
	Fib[1] = 2;
	Fib[2] = 3;
	for( int i = 3; i <= N; i ++ )
		Fib[i] = Fib[i-1] + Fib[i-3];
	go(0, 0);
	cerr << Fib[N] << " " << cnt << endl;
	cerr << (clock() - cl) * 1. / CLOCKS_PER_SEC << endl;
}
 
inline int GetBitmask( int max_n, int i, int j ) {
	int result = i + j * max_n;
	return result;
}
 
inline bool isset( int n, int i ) {
	return n & (1 << i);
}
 
string binary( int n ) {
	string s;
	for( int i = 0; i < 4; i ++ )
		if( n & (1 << i) )
			s = string("1") + s;
		else
			s = string("0") + s;
	return s;
}
 
int t, n, m, benefit[N][N];
int mat[2][MAXSIZE];
 
int solve() {
	memset(mat, 0, sizeof mat);
	int idx = 0;
	for( int x = n - 1; x >= 0; x -- ) {
		for( int y = m - 1; y >= 0; y -- ) {
			int pidx = 1 - idx;
			for( int i = 0; i < Fib[y]; i ++ )
				for( int j = 0; j < Fib[m - y]; j ++ ) {
					int bm = GetBitmask(Fib[y], i, j);
					mat[idx][bm] = 0;
 
					// Try selecting
					if(!isset(bitmasks[i], 0) && !isset(bitmasks[i], 1) && !isset(bitmasks[j], m - y - 1)) {
						if( y == m - 1 )
							mat[idx][bm] >?= benefit[x][y] + mat[pidx][GetBitmask(Fib[0], 0, next_fib[i][1])];
						else {
							int tbm = isset(bitmasks[j], m - y - 1) ? (j - Fib[m - y - 1]) : j;
							mat[idx][bm] >?= benefit[x][y] + mat[pidx][GetBitmask(Fib[y + 1], next_fib[i][1], tbm)];
						}
					}
 
					// Try Ignoring
					if( y == m - 1 )
						mat[idx][bm] >?= mat[pidx][GetBitmask(Fib[0], 0, next_fib[i][0])];
					else {
						int tbm = isset(bitmasks[j], m - y - 1) ? (j - Fib[m - y - 1]) : j;
						mat[idx][bm] >?= mat[pidx][GetBitmask(Fib[y + 1], next_fib[i][0], tbm)];
					}
				}
			idx = pidx;
		}
	}
	return mat[1-idx][0];
}
 
int main() {
	int sc = clock();
	freopen( "grid.in", "r", stdin );
	freopen( "grid.out", "w", stdout);
	pre_process();
	cerr << "Done" << endl;
	for( scanf("%d", &t); t--; ) {
		int cl = clock();
		scanf("%d %d", &n, &m);
		for( int i = 0; i < n; i ++ )
			for( int j = 0; j < m; j ++ )
				scanf("%d", &benefit[i][j]);
		printf("%d\n", solve());
		cerr << (clock() - cl) * 1. / CLOCKS_PER_SEC << endl;
	}
	cerr << (clock() - sc) * 1. / CLOCKS_PER_SEC << endl;
	return 0;
}

 
implementation/iaum_c3_6_grid.txt · Last modified: 2009/07/17 12:38 by hadi
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki