二次联通门 : codevs 1166 矩阵取数游戏
/* codevs 1166 矩阵取数游戏 SB区间dp dp[l][r] = max (dp[l + 1][r] + number[l], dp[l][r - 1] + number[r]) * 2;
不过要套高精 我用的高精是全部封装好的
可以像平时的int等类型用 缺点就是慢。。。
慢差不多1/3吧。。
*/
#include <iostream>
#include <cstdio>
#include <vector>
#include <iomanip>
#include <cassert>
#include <algorithm> #define int64 long long using namespace std; #define Max 105 const int B = ;
const int L = ; inline int intcmp(int a, int b)
{
if (a > b)
return ;
else if (a < b)
return -;
else
return ;
} void read (int &now)
{
now = ;
register char word = getchar ();
while (word < '' || word > '')
word = getchar ();
while (word >= '' && word <= '')
{
now = now * + word - '';
word = getchar ();
}
}
struct BigInt
{ vector<int> a;
BigInt(){}
BigInt(int n)
{
while (n > )
a.push_back(n % B), n /= B;
} BigInt(int64 n)
{
while (n > )
a.push_back(n % B), n /= B;
}
inline void clr0()
{
while (!a.empty() && a.back() == )
a.pop_back();
}
inline BigInt &operator+=(const BigInt &rhs)
{
a.resize(max(a.size(), rhs.a.size()));
int t = ;
for (int i = ; i < (int)rhs.a.size(); i++)
{
a[i] += rhs.a[i] + t;
t = a[i] >= B;
a[i] -= B & (-t);
}
for (int i = (int)rhs.a.size(); t != && i < (int)a.size(); i++)
{
a[i] += t;
t = a[i] >= B;
a[i] -= B & (-t);
}
if (t != )
a.push_back(t);
return *this;
}
inline BigInt &operator-=(const BigInt &rhs)
{
a.resize(max(a.size(), rhs.a.size()));
int t = ;
for (int i = ; i < (int)rhs.a.size(); i++)
{
a[i] -= rhs.a[i] + t;
t = a[i] < ;
a[i] += B & (-t);
}
for (int i = (int)rhs.a.size(); t != && i < (int)a.size(); i++)
{
a[i] -= t;
t = a[i] < ;
a[i] += B & (-t);
}
clr0();
return *this;
}
inline BigInt &operator*=(const BigInt &rhs)
{
int na = (int)a.size();
a.resize(na + rhs.a.size());
for (int i = na - ; i >= ; i--)
{
int ai = a[i];
int64 t = ;
a[i] = ;
for (int j = ; j < (int)rhs.a.size(); j++)
{
t += a[i + j] + (int64)ai * rhs.a[j];
a[i + j] = t % B;
t /= B;
}
for (int j = (int)rhs.a.size(); t != && i + j < (int)a.size(); j++)
{
t += a[i + j];
a[i + j] = t % B;
t /= B;
}
assert(t == );
}
clr0();
return *this;
}
inline BigInt &operator/=(const BigInt &rhs)
{
return *this = div(rhs);
}
inline BigInt &operator%=(const BigInt &rhs)
{
return div(rhs), *this;
}
inline BigInt &shlb(int l = )
{
if (a.empty())
return *this;
a.resize(a.size() + l);
for (int i = (int)a.size() - ; i >= l; i--)
a[i] = a[i - l];
for (int i = ; i < l; i++)
a[i] = ;
return *this;
}
inline BigInt &shrb(int l = )
{
for (int i = ; i < (int)a.size() - l; i++)
a[i] = a[i + l];
a.resize(max((int)a.size() - l, ));
return *this;
}
inline int cmp(const BigInt &rhs) const
{
if (a.size() != rhs.a.size())
return intcmp(a.size(), rhs.a.size());
for (int i = (int)a.size() - ; i >= ; i--)
if (a[i] != rhs.a[i])
return intcmp(a[i], rhs.a[i]);
return ;
}
inline BigInt div(const BigInt &rhs)
{
assert(!rhs.a.empty());
if (rhs > *this)
return ;
BigInt q, r;
q.a.resize((int)a.size() - (int)rhs.a.size() + );
for (int i = (int)a.size() - ; i > (int)a.size() - (int)rhs.a.size(); i--)
{
r.shlb();
r += a[i];
}
for (int i = (int)a.size() - (int)rhs.a.size(); i >= ; i--)
{
r.shlb();
r += a[i];
if (r.cmp(rhs) < )
q.a[i] = ;
else
{
int le = , ri = B;
while (le != ri)
{
int mi = (le + ri) / ;
if ((rhs * mi).cmp(r) <= )
le = mi + ;
else
ri = mi;
}
q.a[i] = le - ;
r -= rhs * q.a[i];
}
}
q.clr0();
*this = r;
return q;
}
friend inline BigInt operator+(const BigInt &lhs, const BigInt &rhs)
{
BigInt res = lhs;
return res += rhs;
}
friend inline BigInt operator-(const BigInt &lhs, const BigInt &rhs)
{
BigInt res = lhs;
return res -= rhs;
}
friend inline BigInt operator*(const BigInt &lhs, const BigInt &rhs)
{
BigInt res = lhs;
return res *= rhs;
}
friend inline BigInt operator/(const BigInt &lhs, const BigInt &rhs)
{
BigInt res = lhs;
return res.div(rhs);
}
friend inline BigInt operator%(const BigInt &lhs, const BigInt &rhs)
{
BigInt res = lhs;
return res.div(rhs), res;
}
friend inline ostream &operator<<(ostream &out, const BigInt &rhs)
{
if (rhs.a.size() == )
out << "";
else
{
out << rhs.a.back();
for (int i = (int)rhs.a.size() - ; i >= ; i--)
out << setfill('') << setw(L) << rhs.a[i];
}
return out;
}
friend inline bool operator<(const BigInt &lhs, const BigInt &rhs)
{
return lhs.cmp(rhs) < ;
}
friend inline bool operator<=(const BigInt &lhs, const BigInt &rhs)
{
return lhs.cmp(rhs) <= ;
}
friend inline bool operator>(const BigInt &lhs, const BigInt &rhs)
{
return lhs.cmp(rhs) > ;
}
friend inline bool operator>=(const BigInt &lhs, const BigInt &rhs)
{
return lhs.cmp(rhs) >= ;
}
friend inline bool operator==(const BigInt &lhs, const BigInt &rhs)
{
return lhs.cmp(rhs) == ;
}
friend inline bool operator!=(const BigInt &lhs, const BigInt &rhs)
{
return lhs.cmp(rhs) != ;
}
}; inline BigInt BigInt_max (BigInt a, BigInt b)
{
return a > b ? a : b;
} int N, M; int number[Max]; BigInt dp[Max][Max];
BigInt Answer; int main (int argc, char *argv[])
{
ios :: sync_with_stdio (false);
read (N);
read (M); for (int i = ; i <= N; i ++)
{
for (register int pos = ; pos <= M; pos ++)
for (register int __pos = ; __pos <= M; __pos ++)
dp[pos][__pos] = ;
for (register int pos = ; pos <= M; pos ++)
{
read (number[pos]);
dp[pos][pos] = * number[pos];
} for (register int size = ; size < M; size ++)
for (register int l = ; l + size <= M; l ++)
{
register int r = l + size;
dp[l][r] = * BigInt_max (dp[l + ][r] + number[l], dp[l][r - ] + number[r]);
}
Answer += dp[][M];
}
cout << Answer;
return ;
}