/** 2017 ACM/ICPC Asia Regional Shenyang Online 解題報告 題目:hdu6199 gems gems gems 連接:http://acm.hdu.edu.cn/showproblem.php?pid=6199 題意:Alice和Bob從左到右取數字,一開始Alice能夠取1個或者2個。以後當前者能夠取得數字個數爲k或者k+1個。 k爲上一我的選的數字個數。若是當前者選不到k個或者k+1個,那麼遊戲結束。 兩我的都用最科學的方法取數字。問Alice的total value - Bob的total value最大。 思路:dp+博弈 因爲k*(k+1)<=2e4;因此k不超過200; 定義dp[i][k]表示從i開始取數字,能夠取k個或者k+1個能夠得到的最大差值。 dp[i][k] = max(sum[i+k-1]-dp[i+k][k],sum[i+k]-dp[i+k+1][k+1])-sum[i-1]; 當前本身選的數的和-下一我的能夠得到的最大差值=本身能夠得到的最大差值。 比賽的時候搞錯了題意。。。 時限1000ms dfs作法超時。 改成遞推200多ms。 */ #include<bits/stdc++.h> using namespace std; #define ms(x,y) memset(x,y,sizeof x) const int maxn = 2e4+10; const int inf = 0x3f3f3f3f; int n; int v[maxn], dp[maxn][202]; int sum[maxn]; /* int dfs(int i,int k) { if(i+k-1>n) return 0; if(i+k-1==n) return sum[n]-sum[i-1]; if(vis[i][k]) return dp[i][k]; vis[i][k] = true; int &res = dp[i][k]; res = max(sum[i+k-1]-sum[i-1]-dfs(i+k,k),sum[i+k]-sum[i-1]-dfs(i+k+1,k+1)); return res; }*/ int main() { int T; cin>>T; while(T--) { scanf("%d",&n); for(int i = 1; i <= n; i++) scanf("%d",&v[i]); for(int i = 1; i <= n; i++) sum[i] = sum[i-1]+v[i]; ms(dp,0); for(int i = n; i >= 1; i--){ for(int k = 200; k >= 1; k--){ if(i+k-1>n) continue; if(i+k-1==n) dp[i][k] = sum[n]-sum[i-1];///選k個。 else{ dp[i][k] = max(sum[i+k-1]-dp[i+k][k],sum[i+k]-dp[i+k+1][k+1])-sum[i-1]; } } } printf("%d\n",dp[1][1]); } return 0; } /* 10 3 1 3 2 2 1 -1 3 1 1 1 4 2 2 3 3 2 1 2 */