题意太清楚不过了。
思路:
如果不考虑高精度的问题就是一个很简单的逆向分析的问题,之前有过这样的一个题目的分析。就是先确定最后一个数,再扩展到两个,三个,...,m个数。f[X][Y]记录最后取a[X]到a[Y]时能得到的最大的数。递推方程就是:f[i][j] = max(f[i][j-1] + a[j]*pow, f[i+1][j] + a[i]*pow),其中pow是当时所需要乘的数。
再把高精度加进去即可。。。高精度只要加法,乘以小整数和比较大小。。。
#include <iostream>
#include <cstring>
using namespace std;
#define N 85
#define MAXL 50
int r, c, arr[N];
class BigInt
{
public:
int data[MAXL];
BigInt()
{
memset(data, 0, sizeof(data));
data[0] = 1;
}
BigInt(const string &s)
{
memset(data, 0, sizeof(data));
data[0] = s.length();
for (int i = 1; i <= data[0]; ++ i)
data[i] = s[data[0]-i] - '0';
}
BigInt operator = (const BigInt &ob)
{
memcpy(data, ob.data, sizeof(data));
return *this;
}
BigInt operator + (const BigInt &ot)
{
BigInt sum;
sum.data[0] = data[0]>ot.data[0] ? data[0] : ot.data[0];
int i;
for (i = 1; i <= sum.data[0]; ++ i)
{
sum.data[i] += data[i] + ot.data[i];
sum.data[i+1] += sum.data[i] / 10;
sum.data[i] %= 10;
}
while (sum.data[i] != 0)
{
sum.data[i+1] += sum.data[i] / 10;
sum.data[i] %= 10;
i ++;
}
sum.data[0] = i - 1;
while(sum.data[sum.data[0]] == 0 && sum.data[0] > 1)
sum.data[0] -= 1;
return sum;
}
BigInt operator * (const int n)
{
BigInt product;
int i;
for (i = 1; i <= data[0]; ++ i)
{
product.data[i] += data[i] * n;
product.data[i+1] += product.data[i] / 10;
product.data[i] %= 10;
}
while (product.data[i] != 0)
{
product.data[i+1] += product.data[i] / 10;
product.data[i] %= 10;
i ++;
}
product.data[0] = i - 1;
while(product.data[product.data[0]] == 0 && product.data[0] > 1)
product.data[0] -= 1;
return product;
}
bool operator < (const BigInt &ob)
{
if (data[0] != ob.data[0]) return data[0] < ob.data[0];
for (int i = data[0]; i >= 1; -- i)
if (data[i] != ob.data[i]) return data[i] < ob.data[i];
return false;
}
friend ostream& operator << (ostream &os, BigInt &ob)
{
for (int i = ob.data[0]; i >= 1; -- i)
os << ob.data[i];
return os;
}
friend istream& operator >> (istream &is, BigInt &ob)
{
string s;
is >> s;
ob = BigInt(s);
return is;
}
};
BigInt ans, pow2[N], t1, t2;
BigInt f[N][N];
void init()
{
pow2[0] = BigInt("1");
for (int i = 1; i < N; ++ i)
pow2[i] = pow2[i-1] * 2;
}
int main()
{
bool start = true;
init();
while (cin >> r >> c)
{
if (start) start = false;
else cout << endl;
ans = BigInt();
while (r --)
{
for (int i = 1; i <= c; ++ i)
{
cin >> arr[i];
f[i][i] = pow2[c] * arr[i];
}
for (int i = 2; i <= c; ++ i)
{
for (int j = 1; j <= c-i+1; ++ j)
{
t1 = f[j][j+i-2] + pow2[c-i+1]*arr[j+i-1];
t2 = f[j+1][j+i-1] + pow2[c-i+1]*arr[j];
if (t1 < t2) f[j][j+i-1] = t2;
else f[j][j+i-1] = t1;
}
}
ans = ans + f[1][c];
}
cout << ans << endl;
}
}