Game (range dp) with a 10891 sum (range dp), 10891dp
Zookeeper
Given n numbers, A and B can select any number from both ends of the number, and can only be selected from one end at A time. And a B tries its best to make the result of his choice the largest. It can be understood that each step of a B is the best. If A is selected first, the maximum difference between A and B is.
Train of Thought: use d [I] [j] to indicate the maximum total score that the current player can obtain by taking the first hand. Because the total score is certain, the state transition equation is
D [I] [j] = sum (I, j)-min (minleft (I + 1, j), minright (I, J-1), 0)
Minleft (I, j) indicates min (d [I] [j], d [I + 1] [j]... d [j] [j]).
Minright (I, j) represents min (d [I] [j], d [I] [J-1]... d [I] [I])
The time complexity is O (n * n)
#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<queue> #include<stack> #include<string>#include<map> #include<set>#define eps 1e-6 #define LL long long using namespace std; const int maxn = 100 + 5;const int INF = 0x3f3f3f3f;int A[maxn], d[maxn][maxn], minleft[maxn][maxn], minright[maxn][maxn], s[maxn];int n;void init() {scanf("%d", &A[0]); s[0] = A[0];for(int i = 1; i < n; i++) {scanf("%d", &A[i]);s[i] = s[i-1] + A[i];}}void solve() {for(int i = 0; i < n; i++) {d[i][i] = A[i];minleft[i][i] = d[i][i];minright[i][i] = d[i][i];}for(int j = 2; j <= n; j++) {for(int i = 0; i+j-1 < n; i++) {int mintmp = min(minleft[i+1][i+j-1], minright[i][i+j-2]);d[i][i+j-1] = s[i+j-1] - s[i] + A[i] - min(mintmp, 0);minleft[i][i+j-1] = min(d[i][i+j-1], minleft[i+1][i+j-1]);minright[i][i+j-1] = min(d[i][i+j-1], minright[i][i+j-2]);}}//cout << d[0][n-1] << endl;printf("%d\n", 2*d[0][n-1]-s[n-1]);}int main() {freopen("input.txt", "r", stdin);while(scanf("%d", &n) == 1 && n) {init();solve();}return 0;}