Problem:
勢力の予想
信夫くんと静夫くんは長方形の島で領地を取り合うゲームをしています。下の図①のように、島全体は格子状に区切られた正方形の区画でできており、区画にはそこから生じる損得が整数で示されています。
このゲームでは１つの駒を動かして領地の境界線を決めていきます。ゲーム開始時、駒は島の北西端にあります（図①）。この駒を島の南東端まで動かしていったときの駒の軌跡が領地の境界線となります。二人のプレーヤーは交互に駒を動かします。駒は南隣の格子点か東隣の格子点にのみ動かすことができます（図②）。駒が島の端に到達した場合は、南か東のうち動かせる方向に動かします。駒が南東端に到達したらゲーム終了です。
ゲーム終了後の境界線から北東側の領域が先攻プレーヤーの領域、南西側の領域が後攻プレーヤーの領
域です（図③）。各プレーヤーの領域内に含まれる、区画から生じる損得の合計がそのプレーヤーのス
コアとなります。二人ともゲームにはかなり慣れており、最終的に自分のスコアから相手のスコアをひ
いた値が一番大きくなるように正確に駒を動かします。
島の大きさとそれぞれの区画から生じる損得が与えられたとき、ゲーム終了時の結果を計算するプログラムを作成せよ。結果は、信夫くんと静夫くんのスコアの差の絶対値とする。
Input
入力は以下の形式で与えられる。
W
H
s
1,1
s
1,2
...
s
1,W
s
2,1
s
2,2
...
s
2,W
:
s
H,1
s
H,2
...
s
H,W
１行目に島に含まれる東西方向と南北方向の区画の数
W
,
H
(1 ≤
W
,
H
≤ 1000) が与えられる。続く
H
行に
i
行
j
列目の区画から生じる損得
s
i,j
(-1000 ≤
s
i,j
≤ 1000) が与えられる。ただし、
i
の値が増加する方向を南、
j
の値が増加する方向を東とする。
Output
信夫くんと静夫くんのスコアの差の絶対値を１行に出力する。
Sample Input 1
2 1
-2 1
Sample Output 1
1
Sample Input 2
2 2
2 -3
3 -1
Sample Output 2
3
Sample Input 3
5 4
5 3 2 -5 2
2 -4 2 8 -4
2 3 -7 6 7
3 -4 10 -3 -3
Sample Output 3
5

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define int long long
signed main(){
    int H,W;
    cin>>W>>H;
    vector<vector<int>> A(H,vector<int>(W));
    vector<vector<int>> R(H+1,vector<int>(W));
    for(int i=0;i<H;i++)for(int j=0;j<W;j++) cin>>A[i][j];
    for(int i=0;i<H;i++)for(int j=0;j<W;j++) R[i+1][j] += R[i][j]+A[i][j];
    int ans = 0;
    map<pair<int,int>,int> m;
    auto f = [&](auto &&self, int a, int b) -> int {
        if(m.count({a,b})) return m[{a,b}];
        if(b == W) return 0;
        int p = (a+b)%2;
        if(p == 0){
            int ans = -1e18;
            ans = max(ans,self(self,a,b+1)-R[H][b]+2*R[a][b]);
            if(a != H) ans = max(ans,self(self,a+1,b));
            return m[{a,b}] = ans;
        }
        if(p == 1){
            int ans = 1e18;
            ans = min(ans,self(self,a,b+1)-R[H][b]+2*R[a][b]);
            if(a != H) ans = min(ans,self(self,a+1,b));
            return m[{a,b}] = ans;
        }
        return 0;
    };
    cout<<abs(f(f,0,0))<<endl;
}
accuracy: 1
time_ms: 550
memory_kb: 81768
final_rank: 20

code_snippet: #include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#define int long long
using namespace std;

int w, h;
int rs[1001][1001];
bool calced[1001][1001];
int dp[1001][1001];

//[lx, rx), [ly, ry)
int getSum(int ly, int lx, int ry, int rx) {
	return rs[ry][rx] - rs[ry][lx] - rs[ly][rx] + rs[ly][lx];
}

//駒が(y, x)にある状態からスタートしたときに、駒が(0, 0)にあるときに先手だった人が得られるスコア(先手領地 - 後手領地).
int dfs(int y, int x) {
	if (y == h && x == w) { return 0; }
	if (calced[y][x]) return dp[y][x];
	
	vector<int> res;
	
	if (y < h) {
		res.push_back(getSum(y, x, y + 1, w) + dfs(y + 1, x));
	}
	if (x < w) {
		res.push_back(-getSum(y, x, h, x + 1) + dfs(y, x + 1));
	}
	
	int ret;
	if (res.size() == 1) ret = res[0];
	else if ((y + x) % 2 == 0) ret = max(res[0], res[1]);
	else ret = min(res[0], res[1]);
	
	calced[y][x] = true;
	return dp[y][x] = ret;
}

signed main() {
	int i, j;
	
	cin >> w >> h;
	for (i = 1; i <= h; i++) for (j = 1; j <= w; j++) cin >> rs[i][j];
	for (i = 1; i <= h; i++) for (j = 1; j <= w; j++) rs[i][j] += rs[i][j - 1];
	for (j = 1; j <= w; j++) for (i = 1; i <= h; i++) rs[i][j] += rs[i - 1][j];
	cout << abs(dfs(0, 0)) << endl;
	return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 20180
final_rank: 11

code_snippet: #include<bits/stdc++.h>

using namespace std;

int func(){
  int w;
  int h;
  cin >> w >> h;
  vector<vector<int>> table(h,vector<int>(w));
  vector<vector<int>> sums(h+1,vector<int>(w+1,0));
  vector<vector<int>> rows(h+1,vector<int>(w+1,0));
  for(auto &i:table)for(auto &j:i)cin >> j;
  for(int i=0;i<h;++i){
    for(int j=0;j<w;++j){
      sums[i+1][j+1] = table[i][j];
    }
  }
  for(int i=0;i<h+1;++i){
    for(int j=0;j<w;++j){
      sums[i][j+1] += sums[i][j];
    }
  }
  rows = sums;
  for(int i=0;i<h;++i){
    for(int j=0;j<w+1;++j){
      sums[i+1][j] += sums[i][j];
    }
  }
  vector<vector<int>> dp(h,vector<int>(w,0));
  vector<vector<int>> used(h,vector<int>(w,false));
  function<int(int,int,int)> rec = [&](int y,int x,int turn_a) -> int{
    if(y == h){
      return 0;
    }
    if(x == w){
      int v = sums[h][w] - sums[y][w];
      if(turn_a){
        v = -v;
      }
      return v;
    }
    int &it = dp[y][x];
    if(used[y][x])return it;
    used[y][x] = true;
    it = -1e9;
    it = max(it, -rec(y,x+1,not turn_a));
    int left = rows[y+1][x];
    int right = rows[y+1][w] - left;
    int add = left - right;
    if(turn_a)add = -add;
    it = max(it, -rec(y+1,x,not turn_a) + add);
    return it;
  };
  return abs(rec(0,0,true));
}

int main(){
  cout << func() << endl;
}
accuracy: 1
time_ms: 170
memory_kb: 23152
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;

using ll=long long;
using P=pair<ll,int>;
constexpr int inf=1e9+10;

#define rep(i,n) for(int i=0;i<int(n);i++)
#define rep2(i,s,n) for(int i=int(s);i<int(n);i++)

template<typename T>
bool chmax(T &a,T b){
    return (a<b ? a=b,true:false);
}
template<typename T>
bool chmin(T &a,T b){
    return (a>b ? a=b,true:false);
}

struct Q{
    ll a,b;
    Q(ll x,ll y):a(x),b(y){
        ll g=__gcd(a,b);
        a/=g,b/=g;
    }
    Q operator+=(const Q r){
        return (*this)=(*this)+r;
    }
    friend Q operator+(const Q l,const Q r){
        return Q(l.a*r.b+r.a*l.b,l.b*r.b);
    }
    friend Q operator*(const Q l,const Q r){
        return Q(l.a*r.a,l.b*r.b);
    }
    friend ostream& operator<<(ostream &os,Q x){
        os << x.a << '/' << x.b;
        return os;
    }
};
ll pow(int a,int b){
    ll ans=1;
    rep(i,b)ans*=a;
    return ans;
}


int main(){
    cout << fixed << setprecision(20);
    int w,h;
    cin >> w >> h;
    vector<vector<ll>> s(h,vector<ll>(w));
    rep(i,h)rep(j,w)cin >> s[i][j];
    vector<vector<ll>> sum(h+1,vector<ll>(w+1));
    rep(i,h)rep(j,w)sum[i+1][j+1]=s[i][j];
    rep(i,h+1)rep(j,w)sum[i][j+1]+=sum[i][j];
    rep(i,h)rep(j,w+1)sum[i+1][j]+=sum[i][j];
    auto getsum=[&](int li,int lj,int ri,int rj){
        return sum[ri][rj]+sum[li][lj]-sum[ri][lj]-sum[li][rj];
    };

    vector<vector<ll>> dp(h+1,vector<ll>(w+1,-inf));
    for(int i=h;i>=0;i--)for(int j=w;j>=0;j--){
        bool sen=(i+j+1)%2;
        if(i==h && j==w)dp[i][j]=0;
        else if(i==h){
            dp[i][j]=getsum(0,j,h,j+1)*(sen ? 1:-1)-dp[i][j+1];
        }
        else if(j==w){
            dp[i][j]=getsum(i,0,i+1,w)*(sen ? -1:1)-dp[i+1][j];
        }
        else{
            chmax(dp[i][j],getsum(0,j,i,j+1)*(sen ? 1:-1)-dp[i][j+1]);
            chmax(dp[i][j],getsum(i,0,i+1,j)*(sen ? -1:1)-dp[i+1][j]);
        }
    }
    cout << abs(dp[0][0]) << endl;
}
accuracy: 1
time_ms: 150
memory_kb: 26540
final_rank: 13

code_snippet: /* -*- coding: utf-8 -*-
 *
 * 0352.cc: 勢力の予想 
 */

#include<cstdio>
#include<algorithm>
 
using namespace std;

/* constant */

const int MAX_H = 1000;
const int MAX_W = 1000;
const int INF = (1 << 30) - 1;

/* typedef */

/* global variables */

int ass[MAX_H + 1][MAX_W + 1], dp[MAX_H + 1][MAX_W + 1];

/* subroutines */

inline int rect(int i0, int j0, int i1, int j1) {
  return ass[i1][j1] - ass[i1][j0] - ass[i0][j1] + ass[i0][j0];
}

inline void setmin(int &a, int b) { if (a > b) a = b; }
inline void setmax(int &a, int b) { if (a < b) a = b; }

/* main */

int main() {
  int w, h;
  scanf("%d%d", &w, &h);
  for (int i = 0; i < h; i++)
    for (int j = 0; j < w; j++) {
      int aij;
      scanf("%d", &aij);
      ass[i + 1][j + 1] = aij + ass[i + 1][j] + ass[i][j + 1] - ass[i][j];
    }

  for (int i = h; i >= 0; i--)
    for (int j = w; j >= 0; j--) {
      if (i == h && j == w) { dp[i][j] = 0; continue; }

      if (! ((i + j) & 1)) { // First
	dp[i][j] = -INF;
	if (i < h)
	  setmax(dp[i][j], dp[i + 1][j] + rect(i, j, i + 1, w));
	if (j < w)
	  setmax(dp[i][j], dp[i][j + 1] - rect(i, j, h, j + 1));
      }
      else { // Second
	dp[i][j] = INF;
	if (i < h)
	  setmin(dp[i][j], dp[i + 1][j] + rect(i, j, i + 1, w));
	if (j < w)
	  setmin(dp[i][j], dp[i][j + 1] - rect(i, j, h, j + 1));
      }
    }

  printf("%d\n", abs(dp[0][0]));
  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 10784
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
//#define LL int
#define LL long long
#define PA pair<LL,LL>
#define VE vector
#define VL VE<LL>
#define VVL VE<VL>
#define VP VE<PA>
#define PB push_back
#define MP make_pair
#define PQ priority_queue
#define FI first
#define SE second
#define rep(i,n) for(int i=0;i<n;i++)
#define INF 1000000000000000003
//#define INF 1000000003

template<typename T>bool chmax(T &a,T b){
  if(a<b){
    a=b;
    return 1;
  }
  return 0;
}
template<typename T>bool chmin(T &a,T b){
  if(a>b){
    a=b;
    return 1;
  }
  return 0;
}

/*typedef struct{
  VP t;LL f,c,n;
}Node;

struct Dijkstra{
  VE<Node> node;
  Dijkstra(LL n){
    node.resize(n);
    rep(i,n)node[i].n=i,node[i].f=-1,node[i].c=INF;
  }
  void add(LL s,LL e,LL c){
    node[s].t.PB(MP(c,e));
  }
  void run(LL s=0,LL c=0){
    LL i;
    PQ<PA,VP,greater<PA>> pq;
    node[s].c=c;
    pq.push(MP(c,s));
    while(pq.size()){
      PA now=pq.top();
      pq.pop();
      LL nowc=now.FI,nown=now.SE;
      if(nowc>node[nown].c)continue;
      for(auto ne:node[nown].t){
        LL nec=nowc+ne.FI,nen=ne.SE;
        if(chmin(node[nen].c,nec))pq.push(MP(nec,nen)),node[nen].f=nown;
      }
    }
  }
};*/

int main(){
  LL W,H;
  LL sum=0;
  cin>>W>>H;
  VVL s(H,VL(W));
  rep(i,H)rep(j,W){
    cin>>s[i][j];
    sum+=s[i][j];
  }
  VVL S(H,VL(W+1)),dp(W+1,VL(H+1));
  rep(i,H)rep(j,W)S[i][j+1]=S[i][j]+s[i][j];
  for(int i=W;i>=0;i--)for(int j=H;j>=0;j--){
    if(i==W&&j==H)continue;
    if(i==W)dp[i][j]=dp[i][j+1]+S[j][W]-S[j][i];
    else if(j==H)dp[i][j]=dp[i+1][j];
    else{
      if((i+j)&1)dp[i][j]=min(dp[i][j+1]+S[j][W]-S[j][i],dp[i+1][j]);
      else dp[i][j]=max(dp[i][j+1]+S[j][W]-S[j][i],dp[i+1][j]);
    }
  }
  LL A=dp[0][0],B=sum-A;
  cout<<abs(A-B)<<endl;
  /*rep(i,H+1){
    rep(j,W+1)cout<<dp[j][i]<<" ";
    cout<<endl;
  }*/
}
accuracy: 1
time_ms: 150
memory_kb: 26564
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
const int INF = 1000000000;
int main(){
  int W, H;
  cin >> W >> H;
  vector<vector<int>> s(H, vector<int>(W));
  for (int i = 0; i < H; i++){
    for (int j = 0; j < W; j++){
      cin >> s[i][j];
    }
  }
  vector<vector<int>> sh(H, vector<int>(W + 1));
  for (int i = 0; i < H; i++){
    sh[i][W] = 0;
    for (int j = W - 1; j >= 0; j--){
      sh[i][j] = sh[i][j + 1] + s[i][j];
    }
  }
  vector<vector<int>> sv(H + 1, vector<int>(W));
  for (int i = 0; i < W; i++){
    sv[H][i] = 0;
    for (int j = H - 1; j >= 0; j--){
      sv[j][i] = sv[j + 1][i] + s[j][i];
    }
  }
  vector<vector<int>> dp(H + 1, vector<int>(W + 1, -INF));
  dp[H][W] = 0;
  for (int i = H; i >= 0; i--){
    for (int j = W; j >= 0; j--){
      if (i < H){
        if ((i + j) % 2 == 0){
          dp[i][j] = max(dp[i][j], sh[i][j] - dp[i + 1][j]);
        } else {
          dp[i][j] = max(dp[i][j], -sh[i][j] - dp[i + 1][j]);
        }
      }
      if (j < W){
        if ((i + j) % 2 == 1){
          dp[i][j] = max(dp[i][j], sv[i][j] - dp[i][j + 1]);
        } else {
          dp[i][j] = max(dp[i][j], -sv[i][j] - dp[i][j + 1]);
        }
      }
    }
  }
  cout << abs(dp[0][0]) << endl;
}
accuracy: 1
time_ms: 150
memory_kb: 19140
final_rank: 8

code_snippet: #include<iostream>
#include<algorithm>
using namespace std;
int H,W;
int S[1010][1010];
int dp[1010][1010];
main()
{
	cin>>W>>H;
	for(int i=0;i<H;i++)
	{
		for(int j=0;j<W;j++)
		{
			cin>>S[i][j+1];
			S[i][j+1]+=S[i][j];
		}
	}
	for(int i=H;i--;)for(int j=W;j>=0;j--)
	{
		int L=-2e9,R=-2e9;
		L=(S[i][W]-S[i][j]*2)*((i+j)%2==0?1:-1)-dp[i+1][j];
		if(j<W)R=-dp[i][j+1];
		dp[i][j]=max(L,R);
	}
	cout<<abs(dp[0][0])<<endl;
}
accuracy: 1
time_ms: 190
memory_kb: 10984
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
using LL = long long;
using ULL = unsigned long long;
#define rep(i,n) for(int i=0; i<(n); i++)

int H,W;
int G[1000][1000];
int S[1001][1001];

int dp[1001][1001];

int range_sum(int l,int r,int t,int b){
 return S[l][t] - S[l][b] - S[r][t] + S[r][b];
}

int main(){
 cin>>W>>H;
 rep(y,H) rep(x,W) cin>>G[x][y];

 rep(x,W+1) rep(y,H+1) S[x][y]=0;
 rep(x,W) rep(y,H) S[x+1][y+1]=G[x][y];
 rep(x,W+1) rep(y,H) S[x][y+1]+=S[x][y];
 rep(x,W) rep(y,H+1) S[x+1][y]+=S[x][y];

 rep(x,W) rep(y,H) dp[x][y]=0;
 for(int x=W-1; x>=0; x--) for(int y=H-1; y>=0; y--){
  int plan_a = dp[x+1][y] - range_sum(x,x+1,y,H);
  int plan_b = dp[x][y+1] + range_sum(x,W,y,y+1);
  if((x+y)%2==0) dp[x][y]=max(plan_a,plan_b);
  else dp[x][y]=min(plan_a,plan_b);
 }

 cout<<abs(dp[0][0])<<endl;

 return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 14816
final_rank: 9

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;

template <class T, class U>
vector<T> make_v(U size, const T& init){ return vector<T>(static_cast<size_t>(size), init); }

template<class... Ts, class U>
auto make_v(U size, Ts... rest) { return vector<decltype(make_v(rest...))>(static_cast<size_t>(size), make_v(rest...)); }

template<class T> void chmin(T &a, const T &b){ a = (a < b ? a : b); }
template<class T> void chmax(T &a, const T &b){ a = (a > b ? a : b); }

int main() {
    int h, w;
    cin >> w >> h;
    auto S = make_v(h+1, w, 0);
    auto T = make_v(h, w+1, 0);
    for (int i = 0; i < h; ++i) {
        for (int j = 0; j < w; ++j) {
            scanf("%d", &S[i][j]);
            T[i][j] = S[i][j];
        }
    }
    for (int i = h-1; i >= 0; --i) {
        for (int j = w-1; j >= 0; --j) {
            S[i][j] += S[i+1][j];
            T[i][j] += T[i][j+1];
        }
    }
    auto dp = make_v(h+1, w+1, -INF<int>);
    dp.back().back() = 0;
    for (int i = h; i >= 0; --i) {
        for (int j = w; j >= 0; --j) {
            if((i+j)&1){
                if(i) chmax(dp[i-1][j], -dp[i][j]+T[i-1][j]);
                if(j) chmax(dp[i][j-1], -dp[i][j]-S[i][j-1]);
            }else {
                if(i) chmax(dp[i-1][j], -dp[i][j]-T[i-1][j]);
                if(j) chmax(dp[i][j-1], -dp[i][j]+S[i][j-1]);
            }
        }
    }
    cout << abs(dp[0][0]) << "\n";
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 14832
final_rank: 3

code_snippet: #include <bits/stdc++.h>

using namespace std;
int dp[1005][1005],t[1005][1005],T,a,m,n,o;
int dq(int x,int y)
{
    if (x==m && y==n)
        return 0;
    if (dp[x][y]!=o)
        return dp[x][y];

    vector<int> v;

    if (x<m)
        v.push_back(dq(x+1,y));
    if (y<n)
        v.push_back(dq(x,y+1)+t[x][y+1]-(t[m][y+1]-t[x][y+1]));

    int h=(x+y)%2,kq;
    if (h==0)
    {
        kq=-o;
        for (int i=0; i<v.size(); ++i)
            kq=max(kq,v[i]);
    }
    else
    {
        kq=o;
        for (int i=0; i<v.size(); ++i)
            kq=min(kq,v[i]);

    }
    return dp[x][y]=kq;

}
int main()
{
   ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    for (int i=1; i<=m; ++i)
        for (int j=1; j<=n; ++j)
        {
            cin>>a;
            t[i][j]=t[i-1][j]+a;
            T+=a;
        }
    o=2000000000;
    for (int i=0; i<=m; ++i)
        for (int j=0; j<=n; ++j)
            dp[i][j]=o;
    a=(dq(0,0));
    if (a<0)a=-a;
    cout<<a<<endl;
    return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 11252
final_rank: 5

code_snippet: #include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int,int> P;

ll W,H;
ll s[1003][1003];

ll memo[1003][1003];
ll dp[1003][1003];

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    cin >> W >> H;

    for (int i = 0;i < H;i++){
        for (int j = 0;j < W;j++){
            cin >> s[i][j];
        }
    }

    for (int i = 0;i < H;i++){
        ll sum = 0;
        for (int j = 0;j < W;j++){
            sum += s[i][j];
        }
        ll tmp = 0;
        for (int j = 0;j <= W;j++){
            memo[i][j] = tmp-(sum-tmp);
            if((i+j)%2 == 0){
                memo[i][j] *= -1;
            }
            if(j != W) tmp += s[i][j];
        }
    }

    for (int i = H;i >= 0;i--){
        for (int j = W;j >= 0;j--){
            if(i == H) dp[i][j] = 0;
            else if(j == W) dp[i][j] = memo[i][j]-dp[i+1][j];
            else dp[i][j] = max(-dp[i][j+1],memo[i][j]-dp[i+1][j]);
        }
    }

    cout << abs(dp[0][0]) << endl;

    return 0;

}
accuracy: 1
time_ms: 50
memory_kb: 26668
final_rank: 6

code_snippet: #include "bits/stdc++.h"
using namespace std;

using int64 = long long;
using i64 = int64;

const int inf = 1<<30;
const int64 inf64 = 1ll<<60;

#define rep(i,N) for(int i=0; i<(int)N; ++i)

int64 dp[1001][1001];
int s[1001][1001];
i64 sumh[1001][1001], sumw[1001][1001];

signed main() {
	int W, H; cin >> W >> H;
	rep(i, H) rep(j, W) cin >> s[i][j];
	
	rep(i, H) {
		sumh[i][0] = s[i][0];
		for(int j=1; j<W; ++j) sumh[i][j] += sumh[i][j-1] + s[i][j];
	}
	rep(j, W) {
		sumw[0][j] = s[0][j];
		for(int i=1; i<H; ++i) sumw[i][j] += sumw[i-1][j] + s[i][j];
	}
	
	dp[H-1][W-1] = 0;
	for(int i=H; i>=0; --i) {
		for(int j=W; j>=0; --j) {
			if(i == H && j == W) continue;
			
			i64 n1 = inf64;
			if(i + 1 <= H) {
				if(j != 0) n1 = dp[i+1][j] + (sumh[i][W-1] - sumh[i][j-1]);
				else n1 = dp[i+1][j] + sumh[i][W-1];
			}
			
			i64 n2 = inf64;
			if(j + 1 <= W) {
				if(i != 0) n2 = dp[i][j+1] - (sumw[H-1][j] - sumw[i-1][j]);
				else n2 = dp[i][j+1] - sumw[H-1][j];
			}
			
			if((i + j) % 2 == 0) {
				if(n1 == inf64) dp[i][j] = n2;
				else if(n2 == inf64) dp[i][j] = n1;
				else dp[i][j] = max({ n1, n2});
			}
			else {
				dp[i][j] = min({n1, n2});
			}
		}
	}
	
	/*
	rep(i, H + 1) {
		rep(j, W + 1) cout << dp[i][j] << " ";
		cout << endl;
	}*/
	
	
	cout << abs(dp[0][0]) << endl;
}
accuracy: 1
time_ms: 210
memory_kb: 30472
final_rank: 18

code_snippet: #include <iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<math.h>
using namespace std;
typedef long long ll;
#define int long long
typedef vector<int> VI;
typedef pair<int, int> pii;
#define fore(i,a) for(auto &i:a)
#define REP(i,n) for(int i=0;i<n;i++)
#define eREP(i,n) for(int i=0;i<=n;i++)
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define eFOR(i,a,b) for(int i=(a);i<=(b);++i)
#define SORT(c) sort((c).begin(),(c).end())
#define rSORT(c) sort((c).rbegin(),(c).rend())
#define LB(x,a) lower_bound((x).begin(),(x).end(),(a))
#define UB(x,a) upper_bound((x).begin(),(x).end(),(a))
#define INF 1000000000
#define LLINF 9223372036854775807
#define mod 1000000007
//vector<vector<int> > dp;
//vector<vector<vector<int> > > vvvi;
//dp=vector<vector<int> >(N, vector<int>(M,0));
//vector<pair<int,int> > v;
//v.push_back(make_pair(x,y));
//priority_queue<int,vector<int>, greater<int> > q2;
int W, H;
int s[1010][1010] = { 0 };

int score(int i, int j) {
	if ((i + j) % 2 == 0)return (s[i + 1][W] - s[i + 1][j]) - s[i + 1][j];
	return s[i + 1][j] - (s[i + 1][W] - s[i + 1][j]);
}

signed main(){
cin.tie(0);
ios::sync_with_stdio(false);

	int dp[1010][1010];
	cin >> W >> H;
	eFOR(i,1, H) {
		eFOR(j,1, W) {
			cin >> s[i][j];
			s[i][j] += s[i][j - 1];
		}
	}
	
	for (int i = H; i >= 0; i--) {
		for (int j = W; j >= 0; j--) {
			if (i == H)dp[i][j] = 0;
			else if (j == W)dp[i][j] = score(i, j) - dp[i + 1][j];
			else dp[i][j] = max(-dp[i][j + 1], score(i, j) - dp[i + 1][j]);
		}
	}
	cout << abs(dp[0][0]) << endl;


	return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 18956
final_rank: 4

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<set>
#include<queue>
#include<stack>
#include<bitset>
#include<functional>
#include<map>
#include<unordered_set>
using namespace std;
//int p = 998244353;
int p = 1000000007;
#define int long long
#define vel vector<long long>
#define vvel vector<vel>
#define rep(i,n) for(int i=0;i<n;i++)
#define sor(v) sort(v.begin(),v.end())
#define mmax(a,b) a=max(a,b)
#define mmin(a,b) a=min(a,b)
#define mkp make_pair
#define pin pair<int,int>
#define qin pair<int,pin>
#define V vector
#define Endl endl
#define veb vector<bool>
#define rev(s) reverse(s.begin(),s.end())
int max_kai = 150000;
vel kai(max_kai, 1);
vel inv_kai;
int rui(int a, int n) {
	if (n == 0) { return 1; }
	int x = rui(a, n / 2);
	x *= x; x %= p;
	if (n % 2 == 1) { x *= a; x %= p; }
	return x;
}
int inv(int a) { return rui(a, p - 2); }
void make_kai() {
	for (int i = 1; i < max_kai; i++) { kai[i] = kai[i - 1] * i; kai[i] %= p; }
	inv_kai = kai;
	rep(i, max_kai) { inv_kai[i] = inv(kai[i]); }
}
int nCr(int n, int r) {
	int a = kai[n] * inv_kai[r]; a %= p;
	a *= inv_kai[n - r]; a %= p;
	return a;
}
vel pa;
int root(int x) {
	if (pa[x] == -1) { return x; }
	int ans = root(pa[x]); pa[x] = ans;
	return ans;
}
void marge(int x, int y) {
	x = root(x);
	y = root(y);
	if (x != y) {pa[x] = y;}
}
#define lower(h,val) lower_bound(h.begin(),h.end(),val)-h.begin()
#define upper(h,val) upper_bound(h.begin(),h.end(),val)-h.begin()
int num_lp(int a, vel &nex) {
	unordered_set<int> se;
	int ans = 0;
	while (true) {
		if (se.find(a) != se.end()) {
			break;
		}
		se.insert(a);
		a = nex[a];
		ans++;
	}
	return ans;
}
int find_cr(int a, vel &nex) {
	unordered_set<int> se;
	while (true) {
		if (se.find(a) != se.end()) {break;}
		se.insert(a);
		a = nex[a];
	}
	return num_lp(a, nex);
}
int inf = 2000000000;
vvel dp;
int solve(vvel &sum, int i, int j, bool is_f) {
	int h = sum.size(); h--;
	int w = sum[0].size();
	if (i == h || j == w) { return 0; }
	if (dp[i][j] == inf) {
		int ans1 = solve(sum, i + 1, j, !is_f);
		int ans2 = solve(sum, i, j + 1, !is_f);
		ans2 += sum[i][j];
		if (is_f) {
			dp[i][j] = min(ans1, ans2);
		}
		else {
			dp[i][j] = max(ans1, ans2);
		}
	}
	return dp[i][j];
}
signed main(){
	int w, h; cin >> w >> h;
	vvel s(h, vel(w));
	int sum1 = 0;
	rep(i, h) {
		rep(j, w) {
			cin >> s[i][j];
			sum1 += s[i][j];
		}
	}
	vvel sum(h + 1, vel(w, 0));
	dp = vvel(h + 1, vel(w +1,inf));
	rep(j, w) {
		for (int i = h - 1; i >= 0; i--) {
			sum[i][j] = sum[i + 1][j] + s[i][j];
		}
	}
	cout << abs(solve(sum, 0, 0, true)*2-sum1) << endl;
	return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 27620
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define rep(i,s,e) for(i64 (i) = (s);(i) < (e);(i)++)
#define all(x) x.begin(),x.end()
#define let auto const

template<typename... Types>
struct dynarr: std::vector<Types...> {
  using std::vector<Types...>::vector;
  using size_type = typename std::vector<Types...>::size_type;
  auto&& operator[](size_type i) { return this->at(i); }
  auto&& operator[](size_type i) const { return this->at(i); }
};

int main() {
  i64 W, H;
  cin >> W >> H;
  dynarr<dynarr<i64>> s(H, dynarr<i64>(W));
  rep(i,0,H) rep(j,0,W) cin >> s[i][j];
  dynarr<dynarr<i64>> Hsum(H + 1, dynarr<i64>(W));
  dynarr<dynarr<i64>> Wsum(H, dynarr<i64>(W + 1));
  rep(j,0,W) rep(i,0,H) {
    Hsum[i + 1][j] = Hsum[i][j] + s[i][j];
  }
  rep(i,0,H) rep(j,0,W) {
    Wsum[i][j + 1] = Wsum[i][j] + s[i][j];
  }
  dynarr<dynarr<i64>> dp(H + 1, dynarr<i64>(W + 1));
  dp[H][W] = 0;
  for(int i = H; i >= 0; i--) {
    for(int j = W;j >= 0;j--) {
      if(i == H && j == W) continue;
      if((i + j) % 2 == 0) {
        dp[i][j] = -1e18;
        // left ... +
        if(j + 1 <= W) {
          dp[i][j] = max(dp[i][j], dp[i][j + 1] + Hsum[i][j]);
        }
        // up ... -
        if(i + 1 <= H) {
          dp[i][j] = max(dp[i][j], dp[i + 1][j] - Wsum[i][j]);
        }
      }
      else {
        dp[i][j] = 1e18;
        if(j + 1 <= W) {
          dp[i][j] = min(dp[i][j], dp[i][j + 1] + Hsum[i][j]);
        }
        // up ... +
        if(i + 1 <= H) {
          dp[i][j] = min(dp[i][j], dp[i + 1][j] - Wsum[i][j]);
        }
      }
    }
  }
  cout << abs(dp[0][0]) << endl;
}
accuracy: 1
time_ms: 210
memory_kb: 34204
final_rank: 19

code_snippet: #include <bits/stdc++.h>

using namespace std;

using i64 = int64_t;
const i64 MOD = 1e9 + 7;
const i64 INF = i64(1e18) + 7;

struct RectangleSum{
    vector<vector<i64>> sum;
    i64 h, w;
    RectangleSum(vector<vector<i64>>& v) :
        h(v.size()),
        w(v[0].size())
    {
        sum.assign(h + 1, vector<i64>(w + 1, 0));
        for(i64 i = 0; i < h; ++i)
            for(i64 j = 0; j < w; ++j)
                sum[i + 1][j + 1] = v[i][j];

        for(i64 i = 0; i < h + 1; ++i)
            for(i64 j = 0; j < w; ++j)
                sum[i][j + 1] += sum[i][j];
        for(i64 j = 0; j < w + 1; ++j)
            for(i64 i = 0; i < h; ++i)
                sum[i + 1][j] += sum[i][j];
    }
    i64 getSum(i64 sx, i64 sy, i64 ex, i64 ey){
        return sum[ex][ey] + sum[sx][sy] - sum[sx][ey] - sum[ex][sy];
    }

};

signed main(){
    i64 w, h;
    cin >> w >> h;
    vector<vector<i64>> v(h, vector<i64>(w));
    for(auto& x : v)
        for(auto& y : x)
            cin >> y;

    RectangleSum r(v);

    vector<vector<i64>> dp(h + 1, vector<i64>(w + 1, -INF));
    dp[h][w] = 0;
    function<i64(i64,i64)> f = [&](i64 x, i64 y){
        if(dp[x][y] != -INF)
            return dp[x][y];
        i64 res_1 = (x == h ? -INF : -f(x + 1, y) + ((x + y) % 2 == 1 ? 1 : -1) * r.getSum(x, 0, x + 1, y));
        i64 res_2 = (y == w ? -INF : -f(x, y + 1) + ((x + y) % 2 == 0 ? 1 : -1) * r.getSum(0, y, x, y + 1));
        return dp[x][y] = max(res_1, res_2);
    };
    f(0, 0);
    cout << abs(dp[0][0]) << endl;
}
accuracy: 1
time_ms: 210
memory_kb: 26644
final_rank: 16

code_snippet: #include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
#define int long long int
const int INF = 1001001001001001LL;
const int MOD = 1000000007;


signed main(){
    
    int h, w; cin >> w >> h;
    vector<vector<int>> s(h + 1, vector<int> (w + 1, 0));
    for(int i = 1; i <= h; i++) for(int j = 1; j <= w; j++) cin >> s[i][j];
    for(int i = 1; i <= h; i++) for(int j = 1; j <= w; j++) s[i][j] += s[i][j - 1];
    for(int j = 1; j <= w; j++) for(int i = 1; i <= h; i++) s[i][j] += s[i - 1][j];

    vector<vector<int>> dp(h + 1, vector<int> (w + 1, -1));
    for(int i = 0; i <= h; i++) dp[i][w] = 0;
    for(int j = 0; j <= w; j++) dp[h][j] = 0;

    for(int i = h - 1; i >= 0; i--){
        for(int j = w - 1; j >= 0; j--){
            
            int turn = (i + j) % 2;
                
            if(turn == 0){
                // 先手
                //スコアを最大化したい
                int score = max(dp[i + 1][j] + s[i + 1][w] - s[i + 1][j] - s[i][w] + s[i][j], dp[i][j + 1] - (s[h][j + 1] - s[h][j] - s[i][j + 1] + s[i][j]));
                dp[i][j] = score;
            }else{
                int score = min(dp[i + 1][j] + s[i + 1][w] - s[i + 1][j] - s[i][w] + s[i][j], dp[i][j + 1] - (s[h][j + 1] - s[h][j] - s[i][j + 1] + s[i][j]));
                dp[i][j] = score;
            }
        }
    }
    
    /*
    cout << h << " " << w << endl;
    for(int i = 0; i <= h; i++){
        for(int j = 0; j <= w; j++){
            cout << dp[i][j] << " ";
        }
        cout << endl;
    }*/

    int ans = dp[0][0];
    if(ans < 0) ans = -ans;
    
    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 18736
final_rank: 10

code_snippet: #include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
using namespace std;
using int64 = long long int;
const int64 INF = 1LL << 60;

// first - second
int W, H; int64 dp[1010][1010];
vector< vector<int> > rows;
vector< vector<int> > cols;

int64 solve(int r, int c) {
  // fprintf(stderr, "r = %d, c = %d\n", r, c);
  int64 &res = dp[r][c];
  if(res != INF) return res;
  if(r == H and c == W) return res = 0;
  bool is_second = (r + c) % 2 == 1;
  
  res = (is_second ? INF : -INF);
  // second
  if(is_second) {
    if(r + 1 <= H) {
      int64 val = rows[r][W] - rows[r][c];
      int64 fs = solve(r+1, c);
      fs += val;
      res = min(res, fs);
    }
    if(c + 1 <= W) {
      int64 val = cols[c][H] - cols[c][r];
      int64 fs = solve(r, c+1);
      fs -= val;
      res = min(res, fs);
    }
  }
  // first
  else {
    if(r + 1 <= H) {
      int64 val = rows[r][W] - rows[r][c];
      int64 fs = solve(r+1, c);
      fs += val;
      res = max(res, fs);
    }
    if(c + 1 <= W) {
      int64 val = cols[c][H] - cols[c][r];
      int64 fs = solve(r, c+1);
      fs -= val;
      res = max(res, fs);
    }
  }
  return res;
}

int main() {
  cin >> W >> H;
  rows.resize(H);
  cols.resize(W);
  for(int i=0; i<H; i++) rows[i].emplace_back(0);
  for(int i=0; i<W; i++) cols[i].emplace_back(0);

  for(int i=0; i<H; i++) {
    for(int j=0; j<W; j++) {
      int val; cin >> val;
      rows[i].emplace_back(rows[i].back() + val);
      cols[j].emplace_back(cols[j].back() + val);
    }
  }

  fill(dp[0], dp[H+1], INF);
  cout << abs(solve(0, 0)) << endl;
  return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 18980
final_rank: 15

code_snippet: #include<algorithm>
#include<climits>
#include<cmath>
#include<cstring>
#include<deque>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<vector>

using namespace std;

using lint = long long;
using P = pair<int, int>;
using LLP = pair<long long, long long>;

#define REP(i, x, n) for(int i = (x), i##_len = int(n) ; i < i##_len ; ++i)
#define rep(i, n) for(int i = 0, i##_len = int(n) ; i < i##_len ; ++i)
#define reps(i, n) for(int i = 1, i##_len = int(n) ; i <= i##_len ; ++i)
#define rrep(i, n) for(int i = int(n) - 1 ; i >= 0 ; --i)
#define rreps(i, n) for(int i = int(n) ; i > 0 ; --i)
#define SORT(x) sort((x).begin(), (x).end())
#define SORT_INV(x) sort((x).rbegin(), (x).rend())
#define TWINS(x) cout << ((x) ? "Yay!" : ":(") << endl

const int IINF = (1 << 30) - 1;
const long long LLINF = 1LL << 61;
const int dx4[] = {1, 0, -1, 0}, dy4[] = {0, 1, 0, -1};
const int dx8[] = {1, 1, 0, -1, -1, -1, 0, 1}, dy8[] = {0, -1, -1, -1, 0, 1, 1, 1};
const double EPS = 1e-8;

int w, h;
vector< vector<int> > s;
vector< vector<int> > sum;
int dp[1005][1005];

template<typename T>
bool chmax(T &_a, T _b){
    if(_a < _b){
        _a = _b;
        return true;
    }else{
        return false;
    }
}

template<typename T>
bool chmin(T &_a, T _b){
    if(_a > _b){
        _a = _b;
        return true;
    }else{
        return false;
    }
}

int solve(int i, int j){
    if(dp[i][j] < IINF){
        return dp[i][j];
    }else if(i == h && j == w){
        return dp[i][j] = 0;
    }

    int res;
    if((i + j) % 2 == 0){
        res = -IINF;
        if(i + 1 <= h) chmax(res, solve(i + 1, j) + (sum[i + 1][w] - sum[i + 1][j] - sum[i][w] + sum[i][j]));
        if(j + 1 <= w) chmax(res, solve(i, j + 1) - (sum[h][j + 1] - sum[h][j] - sum[i][j + 1] + sum[i][j]));
    }else{
        res = IINF;
        if(i + 1 <= h) chmin(res, solve(i + 1, j) + (sum[i + 1][w] - sum[i + 1][j] - sum[i][w] + sum[i][j]));
        if(j + 1 <= w) chmin(res, solve(i, j + 1) - (sum[h][j + 1] - sum[h][j] - sum[i][j + 1] + sum[i][j]));
    }

    return dp[i][j] = res;
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);

    cin >> w >> h;

    s.resize(h);
    sum.resize(h + 1);
    sum[0].resize(w + 1);
    rep(i, h){
        s[i].resize(w);
        sum[i + 1].resize(w + 1);
        rep(j, w){
            cin >> s[i][j];
            sum[i + 1][j + 1] = s[i][j];
        }
    }

    rep(i, h + 1){
        reps(j, w){
            sum[i][j] += sum[i][j - 1];
        }
    }

    rep(j, w + 1){
        reps(i, h){
            sum[i][j] += sum[i - 1][j];
        }
    }

    fill(dp[0], dp[1005], IINF);

    cout << abs(solve(0, 0)) << endl;

    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 14720
final_rank: 2