记录编号 193184 评测结果 AAAAAAAAAA
题目名称 [NOIP 2007]矩阵取数游戏 最终得分 100
用户昵称 Gravatar啊吧啦吧啦吧 是否通过 通过
代码语言 C++ 运行时间 0.939 s
提交时间 2015-10-14 07:34:40 内存使用 28.46 MiB
显示代码纯文本
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <fstream>

using namespace std;
struct bignum{
	static const int MOD = 10000;
	int a[11], len;
	bignum(){
		fill(a, a + 11, 0);
		len = 1;
	}
	bignum operator= (const bignum &x){
		fill(a, a + 11, 0);
		len = x.len;
		for (int i = 0; i < 11; ++i)
			a[i] = x.a[i];
		return *this;
	}
	friend bool operator> (const bignum &a, const bignum &b){
		if (a.len != b.len)
			return a.len > b.len;
		for (int i = a.len - 1; i >= 0; --i)
			if (a.a[i] != b.a[i])
				return a.a[i] > b.a[i];
		return false;
	}
	friend bool operator< (const bignum &a, const bignum &b){
		return b > a;
	}
	bignum operator+ (const bignum &x){
		bignum c;
		c.len = max(len, x.len) + 1;
		int g = 0;
		for (int i = 0; i < c.len || g != 0; ++i){
			c.a[i] = a[i] + x.a[i] + g;
			g = c.a[i] / MOD;
			c.a[i] %= MOD;
		}
		while (c.len > 1 && c.a[c.len - 1] == 0)
			--c.len;
		return c;
	}
	bignum operator* (const int &x){
		bignum c;
		c.len = len + 2;
		int g = 0;
		for (int i = 0; i < c.len || g != 0; ++i){
			c.a[i] = a[i] * x + g;
			g = c.a[i] / MOD;
			c.a[i] %= MOD;
		}
		while (c.len > 1 && c.a[c.len - 1] == 0)
			--c.len;
		return c;
	}
	bignum operator+= (const bignum &x){
		return *this = *this + x;
	}
	bignum operator* (const bignum &b){
		bignum c;
		c.len = len + b.len + 1;
		for (int i = 0; i < len; ++i)
			for (int j = 0; j < b.len; ++j)
				c.a[i + j] += a[i] * b.a[j];
		for (int i = 0; i < c.len; ++i){
			c.a[i + 1] += c.a[i] / MOD;
			c.a[i] %= MOD;
		}
		while (c.a[0] > 1 && c.a[c.len - 1] == 0)
			--c.len;
		return c;
	}
	bignum operator*= (const bignum &x){
		return *this = *this * x;
	}
	bignum operator*= (const int &x){
		return *this = *this * x;
	}
};

const int MAX(85);
int n, m, map[MAX][MAX];
bignum dp[MAX][MAX][MAX], ans[MAX], out;

ostream& operator<< (ostream &out, const bignum &x){
	cout << x.a[x.len - 1];
	for (int i = x.len - 2; i >= 0; --i)
		printf("%04d", x.a[i]);
	return out;
}

bignum operator^ (bignum a, int n){
	bignum c;
	c.a[0]= 1;
	while (n){
		if (n & 1)
			c *= a;
		a *= a;
		n >>= 1;
	}
	return c;
}

main()
{
	freopen("game.in", "r", stdin);
	freopen("game.out", "w", stdout);
	bignum w2;
	w2.a[0] = 2;
	cin >> n >> m;
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= m; ++j)
			cin >> map[i][j];
	
	for (int l = m - 1; l >= 0; --l)
		for (int i = 1; i <= n; ++i)
			for (int j = 1; j <= m - l + 1; ++j){
				bignum aa=dp[i][j][j+l+1]+((w2^(m-l))*map[i][j+l]),
				bb=dp[i][j-1][j+l]+(w2^(m-l))*map[i][j-1];
				if (aa < bb)
					dp[i][j][j + l] = bb;
				else
					dp[i][j][j + l] = aa;
			}
	for (int i = 1; i <= n; ++i){
		for (int j = 1; j <= m; ++j)
			if (dp[i][j][j] > ans[i])
				ans[i] = dp[i][j][j];
		out += ans[i];
	}
	
	cout << out;
//	for (; ; );
}