Ibraheem and Husam are playing a game with group of boxes, lined next to each other on a straight line, such that each box contains a card with some value written on it. Ibraheem and Husam already know the values of all cards before the game starts.
Ibraheem and Husam take turns to play the game, Ibraheem starts first. In each turn, a player can take one box from either ends of the line, add the value of the card inside this box to his score, then remove this box from the line.
Knowing that both players play optimally, your task is to calculate the value x - y, such that x is Ibraheem's score at the end of the game, and y is Husam's score at the end of the game.
Input
The first line contains an integer T (1 ≤ T ≤ 500), where T is the number of test cases.
The first line of each test case contains an integer n (1 ≤ n ≤ 103), where n is the number of boxes in the line.
The second line of each test case contains n integers a1, a2, ..., an ( - 103 ≤ ai ≤ 103), giving the values of the cards inside the boxes.
Output
For each test case, print a single line containing its answer.
Input
5 4 3 1 100 5 1 1000 4 -1 100 4 -5 1 -4 1 0
Output
97 1000 92 -4 0
题解思路:
dp[x][y]表示在x到y上先手取得的最大值;
对于每一次取值,应考虑取得让对手取得min(dp[x-1][y],dp[x][y-1]),设sum为x到y的和;
所以动规方程 dp[x][y]=max(sum-dp[x+1][y],sum-dp[x][y-1]);
#include<bits/stdc++.h> #define int long long #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long using namespace std; const int maxn=1e3+10; int dp[maxn][maxn],vis[maxn][maxn],arr[maxn],a[maxn]; int dfs(int l,int r) { if(vis[l][r]) return dp[l][r]; vis[l][r]=1; if(l==r) return dp[l][r]=a[l]; int l1=dfs(l+1,r); int r1=dfs(l,r-1); int sum=arr[r]-arr[l-1]; return dp[l][r]=max(sum-l1,sum-r1); } #undef int int main(){ #define int long long int t; scanf("%lld",&t); while(t--) { mem(dp,0); mem(vis,0); mem(arr,0); int n; scanf("%lld",&n); for(int i=1;i<=n;i++) { scanf("%lld",a+i); arr[i]=arr[i-1]+a[i]; } dfs(1,n); printf("%lld\n",2*dp[1][n]-arr[n]); } return 0; }