区间dp模板,f[i][j]表示[i, j]中最大得分,由于是环,可以把它展开成链,每次合并得分就是两堆的石子总数,很容易得到状态转移方程,f[i][j] = max(f[i][j], f[i][k] + f[k + 1][j] + d(i, j))
#include<bits/stdc++.h>
using namespace std;
#define rep(i,x,y); for(int i=x;i<=y;i++)
#define dec(i,x,y); for(int i=x;i>=y;i--)
#define int long long
#define Int __int128
#define INF 0x3f3f3f3f
#define lson(x) x << 1
#define rson(x) x << 1 | 1
#define FI first
#define SE second
#define mp make_pair
#define pb push_back
#define all(x) x.begin(), x.end()
typedef pair<int, int> PII;
int n, minl, maxl, f1[305][305], f2[305][305], num[305];
int s[305];
inline int d(int i, int j){return s[j] - s[i - 1];}
signed main(void){
cin >> n;
rep(i, 1, n){
cin >> num[i];
num[i + n] = num[i];
}
rep(i, 1, 2 * n){
s[i] = s[i - 1] + num[i];
}
rep(p, 1, n - 1){
for(int i = 1, j = i + p; j < 2 * n && i < 2 * n; i++, j = i + p){
f2[i][j] = INF;
rep(k, i, j - 1){
f1[i][j] = max(f1[i][j], f1[i][k] + f1[k + 1][j] + d(i, j));
f2[i][j] = min(f2[i][j], f2[i][k] + f2[k + 1][j] + d(i, j));
}
}
}
minl = INF;
rep(i, 1, n){
maxl = max(maxl, f1[i][i + n - 1]);
minl = min(minl, f2[i][i + n - 1]);
}
cout << minl << "\n" << maxl << "\n";
}