1. 程式人生 > >codevs 1166 矩陣取數遊戲

codevs 1166 矩陣取數遊戲

bigint else for 封裝 with 好的 push_back lin cassert

二次聯通門 : 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 = 1000000000; const int L = 9; inline int intcmp(int a, int b) { if (a > b) return 1; else if (a < b) return -1; else return
0; } void read (int &now) { now = 0; register char word = getchar (); while (word < 0 || word > 9) word = getchar (); while (word >= 0 && word <= 9) { now = now * 10 + word - 0; word = getchar (); } } struct BigInt { vector
<int> a; BigInt(){} BigInt(int n) { while (n > 0) a.push_back(n % B), n /= B; } BigInt(int64 n) { while (n > 0) a.push_back(n % B), n /= B; } inline void clr0() { while (!a.empty() && a.back() == 0) a.pop_back(); } inline BigInt &operator+=(const BigInt &rhs) { a.resize(max(a.size(), rhs.a.size())); int t = 0; for (int i = 0; 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 != 0 && i < (int)a.size(); i++) { a[i] += t; t = a[i] >= B; a[i] -= B & (-t); } if (t != 0) a.push_back(t); return *this; } inline BigInt &operator-=(const BigInt &rhs) { a.resize(max(a.size(), rhs.a.size())); int t = 0; for (int i = 0; i < (int)rhs.a.size(); i++) { a[i] -= rhs.a[i] + t; t = a[i] < 0; a[i] += B & (-t); } for (int i = (int)rhs.a.size(); t != 0 && i < (int)a.size(); i++) { a[i] -= t; t = a[i] < 0; 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 - 1; i >= 0; i--) { int ai = a[i]; int64 t = 0; a[i] = 0; for (int j = 0; 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 != 0 && i + j < (int)a.size(); j++) { t += a[i + j]; a[i + j] = t % B; t /= B; } assert(t == 0); } 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 = 1) { if (a.empty()) return *this; a.resize(a.size() + l); for (int i = (int)a.size() - 1; i >= l; i--) a[i] = a[i - l]; for (int i = 0; i < l; i++) a[i] = 0; return *this; } inline BigInt &shrb(int l = 1) { for (int i = 0; i < (int)a.size() - l; i++) a[i] = a[i + l]; a.resize(max((int)a.size() - l, 0)); 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() - 1; i >= 0; i--) if (a[i] != rhs.a[i]) return intcmp(a[i], rhs.a[i]); return 0; } inline BigInt div(const BigInt &rhs) { assert(!rhs.a.empty()); if (rhs > *this) return 0; BigInt q, r; q.a.resize((int)a.size() - (int)rhs.a.size() + 1); for (int i = (int)a.size() - 1; 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 >= 0; i--) { r.shlb(); r += a[i]; if (r.cmp(rhs) < 0) q.a[i] = 0; else { int le = 0, ri = B; while (le != ri) { int mi = (le + ri) / 2; if ((rhs * mi).cmp(r) <= 0) le = mi + 1; else ri = mi; } q.a[i] = le - 1; 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() == 0) out << "0"; else { out << rhs.a.back(); for (int i = (int)rhs.a.size() - 2; i >= 0; i--) out << setfill(0) << setw(L) << rhs.a[i]; } return out; } friend inline bool operator<(const BigInt &lhs, const BigInt &rhs) { return lhs.cmp(rhs) < 0; } friend inline bool operator<=(const BigInt &lhs, const BigInt &rhs) { return lhs.cmp(rhs) <= 0; } friend inline bool operator>(const BigInt &lhs, const BigInt &rhs) { return lhs.cmp(rhs) > 0; } friend inline bool operator>=(const BigInt &lhs, const BigInt &rhs) { return lhs.cmp(rhs) >= 0; } friend inline bool operator==(const BigInt &lhs, const BigInt &rhs) { return lhs.cmp(rhs) == 0; } friend inline bool operator!=(const BigInt &lhs, const BigInt &rhs) { return lhs.cmp(rhs) != 0; } }; 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 = 1; i <= N; i ++) { for (register int pos = 1; pos <= M; pos ++) for (register int __pos = 1; __pos <= M; __pos ++) dp[pos][__pos] = 0; for (register int pos = 1; pos <= M; pos ++) { read (number[pos]); dp[pos][pos] = 2 * number[pos]; } for (register int size = 1; size < M; size ++) for (register int l = 1; l + size <= M; l ++) { register int r = l + size; dp[l][r] = 2 * BigInt_max (dp[l + 1][r] + number[l], dp[l][r - 1] + number[r]); } Answer += dp[1][M]; } cout << Answer; return 0; }

codevs 1166 矩陣取數遊戲