/*************************************** zzblack ** 2015-11-21 ** Orz ** ****************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define ls id<<1,l,mid #define rs id<<1|1,mid+1,r #define OFF(x) memset(x,-1,sizeof x) #define CLR(x) memset(x,0,sizeof x) #define MEM(x) memset(x,0x3f,sizeof x) typedef long long ll ; typedef pair pii ; const int maxn = 1e5 + 50 ; const double eps = 1e-10; const int max_index = 62; const int inf = 0x3f3f3f3f ; const int MOD = 1e9+7 ; inline int read(){ char c = getchar(); while (!isdigit(c)) c = getchar(); int x = 0; while (isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); } return x; } int n, m; int num[1100][1100], dp[1100][1100]; int main () { #ifdef LOCAL freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin); // freopen("C:\\Users\\Administrator\\Desktop\\out.txt","w",stdout); #endif while (~scanf("%d%d", &n, &m)) { // printf("%d %d\n", n, m); MEM(dp); for (int i = 1; i <= n; i++) dp[i][0] = 0; for (int j = 1; j <= m; j++) dp[0][j] = 0; dp[0][0] = 0; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { scanf("%d", &num[i][j]); if ((i + j) % 2 == 0) continue; if (i > 2 || j == 1) dp[i][j] = min(dp[i][j], dp[i - 2][j] + num[i][j] * num[i - 1][j]); if (j > 2 || i == 1) dp[i][j] = min(dp[i][j], dp[i][j - 2] + num[i][j] * num[i][j - 1]); if (i > 1 && j > 1) dp[i][j] = min(dp[i][j], dp[i - 1][j - 1] + min(num[i][j] * num[i - 1][j], num[i][j] * num[i][j - 1])); } } cout << dp[n][m] << "\n"; } return 0; }