//两堆数量为n(n<=20) 的牌,每个牌都有份数 //两个人轮流拿牌,可以取两堆数的头或者尾中的一张 //每个人都取最优解 //问第一个人能够取得的最大分数 //记忆化搜索 dp[sa][ta][sb][tb] 表示第一堆剩下sa,ta,第二堆剩下 //sb,tb的最大值 #include<cstdio> #include<cstring> #include<iostream> using namespace std ; const int maxn = 21; int dp[maxn][maxn][maxn][maxn] ; int a[maxn], b[maxn] ; int ss ; int dfs(int sa ,int ta , int sb,int tb, int res) { if(sa > ta && sb > tb) return 0 ; if(dp[sa][ta][sb][tb] != -1) return dp[sa][ta][sb][tb] ; int ans = 0 ; int tmp = 0 ; if(sa <= ta){ ans = max(ans , res-dfs(sa+1,ta,sb,tb,res-a[sa])) ; ans = max(ans , res-dfs(sa,ta-1,sb,tb,res-a[ta])) ; } if(sb <= tb){ ans = max(ans , res-dfs(sa,ta,sb+1,tb,res-b[sb])) ; ans = max(ans , res-dfs(sa,ta,sb,tb-1,res-b[tb])) ; } dp[sa][ta][sb][tb] = ans ; return ans ; } int main() { int t ; scanf("%d" , &t) ; while(t--) { int n ; scanf("%d" , &n) ; int sum = 0 ; for(int i = 1;i <= n;i++){ scanf("%d" ,&a[i]) ; sum += a[i] ; } for(int i = 1;i <= n;i++){ scanf("%d" , &b[i]) ; sum += b[i] ; } memset(dp,-1,sizeof(dp)) ; printf("%d\n" , dfs(1,n,1,n,sum)) ; } }