/** * @author SCaffrey (srius.caffrey@gmail.com) * @date 2015-11-21 18:58:45 * @copyright MIT */ #include // NOLINT #include // NOLINT #include // NOLINT #include // NOLINT #define x1 x11 #define y1 y11 #define f(x, y, z) for (int x = (y), __ = (z); x < __; ++x) #define g(x, y, z) for (int x = (y), __ = (z); x <= __; ++x) #define fd(x, y, z) for (int x = (y), __ = (z); x > __; --x) #define gd(x, y, z) for (int x = (y), __ = (z); x >= __; --x) #ifdef WIN32 #define I64d "%I64d" #define LLU "%I64u" #else #define I64d "%I64d" #define LLU "%llu" #endif typedef long long LL;// NOLINT typedef long double real; const double INF = 1e100; const int oo = ~0u >> 2; const double pi = acos(-1.0); const double EPS = 1e-8; const int MAXN = 100033; int n, m; int a[1033][1033]; LL dp[1033][1033]; LL ans = 0; int main() { #ifdef LOCAL freopen("a.in", "r", stdin); freopen("a.out", "w", stdout); #endif while (~scanf("%d%d", &n, &m)) { ans = 0; g(i, 1, n) g(j, 1, m) scanf("%d", &a[i][j]); if (m == 1) { g(i, 1, n) { if (i & 1)ans += a[i][1] * a[i + 1][1]; } } else if (n == 1) { g(i, 1, m) { if (i & 1)ans += a[1][i] * a[1][i + 1]; } } else { memset(dp, 0x1f, sizeof dp); dp[2][1] = (LL)a[1][1] * a[2][1]; dp[1][2] = (LL)a[1][1] * a[1][2]; int l; for (int s = 5; s <= m + n; s += 2) { g(r, std::max(1, s - n), std::min(m, (s - 1))) { // printf("%d %d\n", std::max(1, s - n), std::min(m, (s - 1))); l = s - r; // printf("%d %d", l, r); //!!! if (l && r) dp[l][r] = std::min(dp[l][r], dp[l - 1][r - 1] + a[l - 1][r] * a[l][r]); if (r > 2) dp[l][r] = std::min(dp[l][r], dp[l][r - 2] + a[l][r - 1] * a[l][r]); if (l && r) dp[l][r] = std::min(dp[l][r], dp[l - 1][r - 1] + a[l][r - 1] * a[l][r]); if (l > 2) dp[l][r] = std::min(dp[l][r], dp[l - 2][r] + a[l - 1][r] * a[l][r]); // printf("`%d", dp[n][m]); } } ans = dp[n][m]; } printf("%I64d\n", ans); } #ifdef LOCAL fclose(stdin); fclose(stdout); #endif return 0; }