luogu1005 矩阵取数游戏
题目大意
一个矩阵,每次从每一行的行首或行尾取一个数,每一行的价值为 取的数*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("\n"); } 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; }