Solution:
首先发现每一行都是独立的。
发现可以dp,设
f
[
i
]
[
j
]
f[i][j]
f[i][j]为
i
i
i到
j
j
j的最大分数。决策有两种,当前取
i
i
i或当前取
j
j
j。
显然要加高精。
具体细节见代码。
code:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const int MAXN = 107;
int N, M;
struct BIGNUM {
int s[MAXN], len;
BIGNUM () {memset(s, 0, sizeof(s)); len = 0;}
BIGNUM operator = (const char *c) {
len = strlen(c);
for(int i = 0; i < len; i++)
s[i] = c[len - i - 1] - '0';
return *this;
}
BIGNUM operator = (const int x) {
char c[MAXN];
sprintf(c, "%d", x);
*this = c;
return *this;
}
BIGNUM operator + (const BIGNUM x) {
BIGNUM c;
c.len = max(len, x.len) + 1;
for(int i = 0; i < c.len; i++) {
c.s[i] += s[i] + x.s[i];
c.s[i + 1] += c.s[i] / 10;
c.s[i] %= 10;
}
while(!c.s[c.len - 1] && c.len > 0) c.len--;
return c;
}
BIGNUM operator * (const BIGNUM x) {
BIGNUM c;
c.len = len + x.len + 1;
for(int i = 0; i < len; i++)
for(int j = 0; j < x.len; j++) {
c.s[i + j] += s[i] * x.s[j];
c.s[i + j + 1] += c.s[i + j] / 10;
c.s[i + j] %= 10;
}
while(!c.s[c.len - 1] && c.len > 0) c.len--;
return c;
}
bool operator < (const BIGNUM x) {
if(len != x.len) return len < x.len;
for(int i = len - 1; i >= 0; i--)
if(s[i] != x.s[i])
return s[i] < x.s[i];
return false;
}
BIGNUM (const char *c) {*this = c;}
BIGNUM (const int x) {*this = x;}
};
istream& operator >> (istream& in, BIGNUM &x) {
char c[MAXN];
scanf("%s", c);
x = c;
return in;
}
ostream& operator << (ostream &out, BIGNUM x) {
if(x.len == 0) printf("0");
for(int i = x.len - 1; i >= 0; i--)
printf("%d", x.s[i]);
return out;
}
BIGNUM a[MAXN][MAXN];
BIGNUM f[MAXN][MAXN];
BIGNUM powe[MAXN];
void dp(int lin) {
memset(f, 0LL, sizeof(f));
powe[0].len = 1; powe[0].s[0] = 1;
BIGNUM sth;
sth.len = 1, sth.s[0] = 2;
for(int i = 1; i <= 100; i++) powe[i] = powe[i - 1] * sth;
for(int i = 1; i <= M; i++) f[i][i] = a[lin][i] * powe[M];
for(int k = 2; k <= M; k++)
for(int i = 1; i + k - 1 <= M; i++) {
int j = i + k - 1;
BIGNUM x = f[i + 1][j] + (a[lin][i] * powe[M - k + 1]),
y = f[i][j - 1] + (a[lin][j] * powe[M - k + 1]);
if(x < y)
f[i][j] = y;
else
f[i][j] = x;
}
}
int main() {
#ifdef test
freopen("test.txt", "r", stdin);
#endif
cin >> N >> M;
for(int i = 1; i <= N; i++)
for(int j = 1; j <= M; j++)
cin >> a[i][j];
BIGNUM ans;
for(int lin = 1; lin <= N; lin++) {
dp(lin); ans = ans + f[1][M];
}
cout << ans;
return 0;
}