题目大意
一个矩阵,每次从每一行的行首或行尾取一个数,每一行的价值为 取的数*2^当前取数的次数,每一次的价值为每一行的价值的和。求得到的价值的最大值。
思路

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX_ROW = 100, MAX_COL = 100;
int A[MAX_ROW][MAX_COL];
int TotRow, TotCol;
struct BigInt
{
private:
static const int MAX_N = 100, BASE = 10000, CARRY = 4;
int A[MAX_N];
int Len;
public:
void Print()
{
printf("%d", A[Len]);
for (int i = Len - 1; i >= 0; i--)
printf("%0*d", CARRY, A[i]);
printf("
");
}
void Clear()
{
memset(A, 0, sizeof(A));
Len = 0;
}
void Set(int x)
{
Clear();
while (x)
{
A[Len++] = x % BASE;
x /= BASE;
}
while (Len > 0 && A[Len] == 0)
Len--;
}
BigInt(int x)
{
Set(x);
}
BigInt()
{
Set(0);
}
BigInt operator =(const BigInt& a)
{
memcpy(A, a.A, sizeof(A));
Len = a.Len;
return *this;
}
BigInt operator *=(const BigInt& a)
{
BigInt b = *this;
Clear();
Len = a.Len + b.Len;
for (int i = 0; i <= a.Len; i++)
for (int j = 0; j <= b.Len; j++)
{
A[i + j] += a.A[i] * b.A[j];
A[i + j + 1] += A[i + j] / BASE;
A[i + j] %= BASE;
}
if (A[Len + 1])
Len++;
return *this;
}
BigInt operator *(const BigInt& a)
{
BigInt ans = *this;
ans *= a;
return ans;
}
BigInt operator +=(const BigInt& a)
{
Len = max(Len, a.Len);
for (int i = 0; i <= Len; i++)
{
A[i] += a.A[i];
A[i + 1] += A[i] / BASE;
A[i] %= BASE;
}
if (A[Len + 1])
Len++;
return *this;
}
BigInt operator +(const BigInt& a)
{
BigInt ans = *this;
ans += a;
return ans;
}
bool operator <(const BigInt& a) const
{
if (Len != a.Len)
return Len < a.Len;
for (int i = Len; i >= 0; i--)
if (A[i] != a.A[i])
return A[i] < a.A[i];
return true;
}
bool Is0()
{
return Len == 0 && A[Len] == 0;
}
}F[MAX_COL][MAX_COL], Pow2[MAX_COL];
bool Vis[MAX_COL][MAX_COL];
void InitPow2(int n)
{
Pow2[0] = 1;
for (int i = 1; i <= n; i++)
Pow2[i] = Pow2[i - 1] * 2;
}
BigInt Dfs(int row, int l, int r)
{
if (l > r)
return 0;
if (Vis[l][r])
return F[l][r];
Vis[l][r] = true;
BigInt a = Dfs(row, l + 1, r) + Pow2[TotCol - r + l] * A[row][l];
BigInt b = Dfs(row, l, r - 1) + Pow2[TotCol - r + l] * A[row][r];
return F[l][r] = a < b ? b : a;
}
BigInt CalRow(int row)
{
memset(Vis, false, sizeof(Vis));
return Dfs(row, 1, TotCol);
}
int main()
{
scanf("%d%d", &TotRow, &TotCol);
InitPow2(TotCol);
for (int i = 1; i <= TotRow; i++)
for (int j = 1; j <= TotCol; j++)
scanf("%d", &A[i][j]);
static BigInt ans(0);
for (int row = 1; row <= TotRow; row++)
ans += CalRow(row);
ans.Print();
return 0;
}