Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

D - インビジブル

Problem Statement

あなたは友達と"インビジブル"というカードゲームを遊ぼうとしている．
このカードゲームでは，"得点カード"と"妨害カード"という2種類のカードを使う．
それぞれの得点カードには，正の値が書かれている．このカードゲームのルールは次の通りである．

ゲームはプレイヤー1とプレイヤー2の2人のプレイヤーで行われる．ゲームはプレイヤー1のターンから始まる．

場には，1つのスタックと2つのデッキがある．スタックは，2人のプレイヤーが置いたカードからなる．また，それぞれのプレイヤーが持つデッキはそのプレイヤーが持つ得点カードと妨害カードからなる．プレイヤーは自分，もしくは相手デッキのカードの順番をいつでも確認できる．ゲームの開始時点ではスタックには1枚もカードはない．

2人のプレイヤーは交互に次の2つの行動のどちらかをちょうど1回行う．

自分のデッキの一番上のカードをスタックの一番上に置く．ただし，この行動は自分のデッキにカードが1枚も存在しない時には行うことができない．

自分のターンをパスする．

プレイヤーがターンをパスした時，次の処理を行う．

各プレイヤーは次の2つの条件を満たすスタック中のすべての得点カードを得る．得た得点カードは場から取り除かれる．

自分がスタックにおいた得点カードである．

相手が置いたどの妨害カードよりも上にある (スタック中に相手の妨害カードが存在しないとき，プレイヤーは自分がスタックに置いたすべてのカードを得る)．

スタックのカードをすべて取り除く．

もしスタックにカードがない状態で両プレイヤーが連続してパスした場合，ゲームを終了する．
各プレイヤーの最終的なスコアは，各プレイヤーが得た得点カードに書かれた数の総和である．

各プレイヤーは，自分のスコアから相手のスコアを引いた値を最大化するために最適な行動をとる．
あなたの仕事は，与えられた各プレイヤーのデッキに対し，各プレイヤーが最適に行動したときのプレイヤー1のスコアとプレイヤー2のスコアの差を計算することである．

Input

入力は次のような形式の単一テストケースからなる．

$n$ $m$

$a_1$ $a_2$ $\dots$ $a_n$

$b_1$ $b_2$ $\dots$ $b_m$

1行目は山札の枚数を表す正の整数 $n$, $m$ ($1 \le n, m \le 50$) からなる．
2行目は $n$ 個の整数からなり，$a_i$ はプレイヤー1のデッキの上から $i$ 番目のカードを表す ($1 \le i \le n$)．$a_i$ は $1$ 以上，$1{,}000{,}000$ 以下，または $-1$ である．
3行目は $m$ 個の整数からなり，$b_j$ はプレイヤー2のデッキの上から $j$ 番目のカードを表す ($1 \le j \le m$)．$b_j$ は $1$ 以上，$1{,}000{,}000$ 以下，または $-1$ である．
$a_i$, $b_j$ が正の整数の時は得点カードを表し，$-1$ の時は妨害カードを表す．

Output

お互いのプレイヤーが最適に行動した時の (プレイヤー1のスコア) - (プレイヤー2のスコア) を出力せよ．

Sample Input 1

2 2
100 -1
200 300

Output for the Sample Input 1

-100

Sample Input 2

3 5
10 30 -1
-1 90 20 10 -1

Output for the Sample Input 2

0

Sample Input 3

4 5
15 20 10 30
50 30 10 20 25

Output for the Sample Input 3

-60

Solution in C++11 (judge verdict: Runtime Error)

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

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define each(itr,v) for(auto itr:v)
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcount

#define INF INT_MAX/3

int n[2];
int card[2][55];
int dp[50][50][50][50][4][2];

ll dfs(ll ai,ll aj,ll bi,ll bj,ll pass,ll turn){
  if(pass==2)return 0;
  if(dp[ai][aj][bi][bj][pass][turn]!=-INF)return dp[ai][aj][bi][bj][pass][turn];
  ll res=-INF;
  if(aj<n[turn]){
    if(card[turn][aj]==-1){
      maxch(res,-dfs(bj,bj,ai,aj+1,0,1-turn));
    }else{
      maxch(res,-dfs(bi,bj,ai,aj+1,0,1-turn));
    }
  }
  if(ai==aj&&bi==bj){
    maxch(res,-dfs(bi,bj,ai,aj,pass+1,1-turn));
  }else{
    ll s1=0,s2=0;
    repl(i,ai,aj){
      if(card[turn][i]!=-1)s1+=card[turn][i];
    }
    repl(i,bi,bj){
      if(card[1-turn][i]!=-1)s2+=card[1-turn][i];
    }
    maxch(res,-dfs(bj,bj,aj,aj,0,1-turn)+(s1-s2));
  }
  return dp[ai][aj][bi][bj][pass][turn]=res;
}

int main(){
	cin.sync_with_stdio(false);
  cin>>n[0]>>n[1];
  rep(k,2)rep(i,n[k])cin>>card[k][i];
  rep(i,50)rep(j,50)rep(k,50)rep(l,50)rep(x,4)rep(y,2)dp[i][j][k][l][x][y]=-INF;
  cout<<dfs(0,0,0,0,0,0)<<endl;
	return 0;
}