You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

56 lines
2.0 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 410; // 注意开双倍空间
int a[N]; // 原始数组
int s[N]; // 前缀和
int f[N][N]; // 最小得分,从i堆合并到j堆的最小代价
int g[N][N]; // 最大得分,从i堆合并到j堆的最大代价
int n, m;
// 搜索出l~r的最小得分
int dfs1(int l, int r) { // 求出最小得分
int &v = f[l][r]; // 利用C++特性定义一个v,简化代码
if (l == r) return v = 0; // l==r时返回0
if (v) return v; // 已保存的状态不必搜索
int res = INF; // 初始值赋为最大值以求最小值
// 枚举l~r之间的每个可能k,之所以k∈[l,r),可以看下面的递推关系式dfs1(k+1,r)决定了k最大是r-1
for (int k = l; k < r; k++)
res = min(res, dfs1(l, k) + dfs1(k + 1, r));
return v = res + s[r] - s[l - 1]; // 记录状态
}
// 搜索出l~r的最大得分
int dfs2(int l, int r) { // 求出最大得分
int &v = g[l][r]; // 利用C++特性定义一个v,简化代码
if (l == r) return v = 0; // 若初始值为0可省略该句
if (v) return v; // l==r时返回0
int res = 0; // 初始值设为0
for (int k = l; k < r; k++)
res = max(res, dfs2(l, k) + dfs2(k + 1, r));
return v = res + s[r] - s[l - 1]; // 记录状态
}
int main() {
scanf("%d", &n);
// 破环成链
for (int i = 1; i <= n; i++) scanf("%d", &a[i]), a[i + n] = a[i];
// 前缀和
for (int i = 1; i <= 2 * n; i++) s[i] = s[i - 1] + a[i];
// 搜索出1-2*n的最小得分
dfs1(1, 2 * n);
// 搜索出1-2*n的最大得分
dfs2(1, 2 * n);
int ans1 = INF, ans2 = 0;
for (int i = 1; i <= n; i++) {
ans1 = min(f[i][n + i - 1], ans1); // 选出最小答案
ans2 = max(g[i][n + i - 1], ans2); // 选出最大答案
}
printf("%d \n%d", ans1, ans2);
return 0;
}